循环NIM游戏

时间:2015-10-25 17:08:22

标签: java

尝试更改此代码,以便它可以像这样播放nim游戏:

01  02  03  04  05  06  07  08  09 
20                              10     
19  18  17  16  15  14  13  12  11

到目前为止,它的打印方式如下:

0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 
0 1 2 3 4 5 6 7.

这是代码:

我知道它的笨重代码,但我还在学习。

public class Main {

public static void main(String[] args) {    
    System.out.println("Let's play the NIM game!");   
    TheNimGame game = new TheNimGame();  
    //Rows rows1 = new Rows();        
    game.StartGame();
}

TheNimGame.java

package com.company;

import java.util.ArrayList;
import java.util.Scanner;


/**
 * Created by SimonBlixenkrone on 21/10/2015.
 */
public class TheNimGame {
    private Scanner scanner = new Scanner(System. in );
    private ArrayList < Player > players = new ArrayList < Player > ();
    private ArrayList < Rows > rows = new ArrayList < Rows > ();
    private int defaultValueForRows = 3;
    //private int maxNumberOfObjectsInRow = 5;
    private int maxNumberOfObjectsInRow = 10;

    public void SetNumberOfRows(int numberOfRows) {
        defaultValueForRows = numberOfRows;
    }

    public void StartGame() {
        // set game
        populateRows();

        //add players
        for (int i = 0; i < 2; i++) {
            System.out.println("Enter name of player " + i + ": ");
            Player player = new Player();
            player.setName(scanner.nextLine());
            players.add(player);
        }

        //run the game
        while (true) {
            printRows();
            takeTurn(players.get(0));
            if (gameover() == true) {
                System.out.println(players.get(0) + " lost the game");
                break;
            }
            printRows();
            takeTurn(players.get(1));
            if (gameover() == true) {
                System.out.println(players.get(1) + " lost the game");
                break;
            }

        }
    }

    private void printRows() {
        for (int i = 0; i < rows.size(); i++) {
            System.out.println(rows.get(i));
        }
    }

    // this methods put a max number of obj in the first row and the one les in the next...
    private void populateRows() {
        for (int i = 0; i < defaultValueForRows; i++) {
            Rows r = new Rows();
            r.setNumberOfObjects(maxNumberOfObjectsInRow - i);
            rows.add(r);
        }
    }

    private boolean gameover() {
        /*for (int i = 0; i < rows.size(); i++)
        {
            if (rows.get(i).getNumberOfObjects() > 0)
            {
                return false;
            }
        }
        return true;*/

        for (Rows row: rows) {
            if (row.getNumberOfObjects() > 0) {
                return false;
            }
        }
        return true;
    }

    private void takeTurn(Player player) {
        System.out.println(player + ": Which row do you want to take obejcts from?");
        int rowNumber = Integer.parseInt(scanner.nextLine());

        Rows row = rows.get(rowNumber - 1);

        System.out.println(player + ": How many object do you want to remove?");
        int numberOfObjects = Integer.parseInt(scanner.nextLine());

        if (player.removeObjects(row, numberOfObjects) == false) {
            takeTurn(player);
        }

    }

}

Rows.java

package com.company;

/**
 * Created by SimonBlixenkrone on 21/10/2015.
 */
public class Rows {
    private int numberOfObjects = 20;
    public int numberInRows = 0;

    public int getNumberOfObjects() {
        return numberOfObjects;
    }

    public void setNumberOfObjects(int numberOfObjects) {
        this.numberOfObjects = numberOfObjects;
    }

    public boolean removeObjects(int numberOfObjects) {
        if (this.numberOfObjects >= numberOfObjects) {
            this.numberOfObjects -= numberOfObjects;
            return true;
        } else return false;
    }

    @Override
    public String toString() {
        String s = "";
        //        for (int i = 0; i < numberOfObjects; i++) {
        for (int i = 0; i < numberOfObjects; i++) {
            //s = s + "|";
            s = s + numberInRows+++" ";
        }
        return s;
    }
}

Player.java

package com.company;

import java.util.Scanner;

/**
 * Created by SimonBlixenkrone on 21/10/2015.
 */
public class Player {
    private String name;
    //private Scanner scanner = new Scanner(System.in);

    public void enterName(Scanner scanner) {
        setName(scanner.nextLine());
    }

    @Override
    public String toString() {
        return getName();
    }

    public boolean removeObjects(Rows rows, int numberOfObjects) {
        if (rows.removeObjects(numberOfObjects)) {
            System.out.println(getName() + " removed " + numberOfObjects + " objects");
            return true;
        } else {
            System.out.println("Not possible! try again");
            return false;
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

1 个答案:

答案 0 :(得分:0)

我很确定我们会选择相同的课程。因为这也是我的任务。 请原谅我仍然贫穷的做法,并随意将方法降级到他们的相关课程。也许这会让你知道我的目标。仍然是WIP。

public class NimGame {

//instantiate scanner object
Scanner scanner = new Scanner(System.in);

private ArrayList<Integer> numbersArray = new ArrayList<>();
private ArrayList<Player> players = new ArrayList<Player>();




public void startGame() {

    fillArrayList(20);
    printArrayListAsCircle();
    //add players
    for (int i = 0; i < 2; i++) {
        System.out.println("Enter name of Player " + (1 + i) + ": ");
        Player player = new Player();
        player.setName(scanner.nextLine());
        players.add(player);
    }

    //run!!!
    while (true) {
        takeTurn(players.get(0));
        if (gameOver() == true) {
            System.out.println(players.get(0) + " lost the game");
            break;
        }
        printArrayListAsCircle();

        takeTurn(players.get(1));
        if (gameOver() == true) {
            System.out.println(players.get(0) + " lost the game");
            break;
        }
        printArrayListAsCircle();

    }
}

private void fillArrayList(int i) {
    //populate arrayList
    for (int j = 1; j <= i; j++) {
        numbersArray.add(j);
    }
}


//worked on this forever, trying (and failing) to implement foreach-loops, while-loops, simple for-loops.
//the result is... not pretty but performs well enough!
//most problems arose with printing the middle part and I must've tried 30 versions until this one worked.
//first I introduce two variables, one 'end'-point and one 'pivot'-point at which to 'wrap' the arraylist around.
//the ascending row is straightforward. run print() on all indices up to but not including the halfwayNumber.
//middle row: i honestly struggle to understand how I arrived there. So much debugging last night I lost it. It works though...
//descending row: analogue to ascending row, run print() on all indices DOWN to the halfwayNumber
public void printArrayListAsCircle() {
    int size = numbersArray.size();
    int halfwayNumber = size / 2;

    int i = 0;
    // Ascending row
    while (i < halfwayNumber-1) {
        print(numbersArray.get(i));
        i++;
    }

    // Middle row
    System.out.println();
    print(numbersArray.get(numbersArray.size()-1));
    for (int j = -1; j < halfwayNumber*2; j++) {
        System.out.print(" ");
    }
    print(numbersArray.get(halfwayNumber-1));
    i = size-2;
    System.out.println();

    // Descending row
    while (i >= halfwayNumber ) {
        print(numbersArray.get(i));
        i--;
    }
    System.out.println();
}

//my print() method. contains some formatting to make the top and bottom row align nicely. at least at the first iteration.
private void print(Integer i) {
    if (i < 10) {
        System.out.print(" " + i + " ");
    } else {
        System.out.print(i + " ");
    }
}

//my new gameOver() method. short and sweet
private boolean gameOver() {
    return numbersArray.size() == 0;
}


//takeTurn() method, changed things around a bit
private void takeTurn(Player player) {
    System.out.println(player + ": please enter a start number");
    int startNumber = Integer.parseInt(scanner.nextLine());
    System.out.println(player + ": please enter an end number");
    int endNumber = Integer.parseInt(scanner.nextLine());
    removeNumbers(startNumber, endNumber);

}

//this took a while and some trial and error, but in the end I came up with an algorithm that works:
//for-loop cycles through the arraylist 'size' times (-> this how often it cycles is dependent on the flexible size of the arraylist)...
// ...and for each iteration increments i to arrive at the next index UNLESS...
//...it finds an index where both if-conditions are found to be true. then i is removed.
//To ensure that ALL numbers in between startNum and endNum are removed as well i is then decremented...
//... because of the arraylist shrinking and assigning new indices to the elements 'shuffled to the left'.
private void removeNumbers(int startNumber, int endNumber) {
    for (int i = 0; i < numbersArray.size(); i++) {
        if (numbersArray.get(i) >= startNumber && numbersArray.get(i) <= endNumber) {
            numbersArray.remove(i);
            i--;
        }
    }
}
}