HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Racetrack in Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
racetrackjavastackoverflow

Problem

Racetrack:

The August community challenge is to implement a program that plays the Racetrack game. Each player starts with an integer position on a square grid. On each turn, the current player can accelerate by -1, 0, or 1 unit in each direction. The first player to reach the finish line wins.

This is a Java implementation of the challenge. Any feedback on any aspect of the program would be appreciated.

Due to the length of this post, the PathFinder and PathFollower classes will be posted separately: Racetrack pathfinding and path following.

I'm sorry about the long lines. I was following a margin line, but I just now realized how far out it was set (120 columns).

Racetrack-Nogui.java

This file has the main function. It loads a track file, feeds the file into a new Track instance, initializes any computer controled players, and drives the gameplay turn by turn. Ideally, I should be able to change the user interface just by replacing this file.

```
package com.erichamion.racetrack;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.*;

public class RacetrackNoGui {

private static final Map KEYMAP = new HashMap<>();
private static final Scanner STDIN = new Scanner(System.in);
private static final Map mComputerPlayers = new HashMap<>();

static {
KEYMAP.put('1', new GridPoint(1, -1));
KEYMAP.put('2', new GridPoint(1, 0));
KEYMAP.put('3', new GridPoint(1, 1));
KEYMAP.put('4', new GridPoint(0, -1));
KEYMAP.put('5', new GridPoint(0, 0));
KEYMAP.put('6', new GridPoint(0, 1));
KEYMAP.put('7', new GridPoint(-1, -1));
KEYMAP.put('8', new GridPoint(-1, 0));
KEYMAP.put('9', new GridPoint(-1, 1));
}

public static void main(String[] args) {
String filename = null;
List playerIndices = new ArrayList<>();

for (String arg : args) {
if (arg.length() == 1 && arg.charAt(0) >= '1' && arg

Solution

One point I want to make is that your algorithm for determining a win is flawed:

// Test for win
        if (winPoint != null) {
            boolean isValidWin = true;
            if ((winDirection.getRow() != 0 && !Util.isSignSame(winDirection.getRow(), player.getVelocity().getRow()))
                    ||
                    (winDirection.getCol() != 0 &&
                            !Util.isSignSame(winDirection.getCol(), player.getVelocity().getCol()))) {
                isValidWin = false;
            }
            if (isValidWin) {
                mWinner = mCurrentPlayer;
                player.setPos(winPoint);
                return;
            }
        }


This only tests if user passes the finish line in the right direction. A player can cheat, as I did, by crossing the finish line in the reverse direction a little and reversing direction. You can prevent this in two ways:

-
either disallowing crossing the finish line in the reverse direction

-
or, if you want to allow crossing the finish line in the reverse direction for some reason, by counting the times it is crossed in each direction, and declare a winner once the player crosses the line in the right direction more than he did in the reverse direction.

Code Snippets

// Test for win
        if (winPoint != null) {
            boolean isValidWin = true;
            if ((winDirection.getRow() != 0 && !Util.isSignSame(winDirection.getRow(), player.getVelocity().getRow()))
                    ||
                    (winDirection.getCol() != 0 &&
                            !Util.isSignSame(winDirection.getCol(), player.getVelocity().getCol()))) {
                isValidWin = false;
            }
            if (isValidWin) {
                mWinner = mCurrentPlayer;
                player.setPos(winPoint);
                return;
            }
        }

Context

StackExchange Code Review Q#101543, answer score: 5

Revisions (0)

No revisions yet.