Skip to content

Instantly share code, notes, and snippets.

@snarkbait
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snarkbait/f13d27b7f5182f18b4a1 to your computer and use it in GitHub Desktop.
Save snarkbait/f13d27b7f5182f18b4a1 to your computer and use it in GitHub Desktop.
import java.util.Random;
public class Game21
{
private int[] heap;
private Random rand = new Random();
private boolean computerOpponent;
private boolean lastPlayWins;
private boolean gameOver;
private boolean multi;
private int tokens;
private Player winner;
private Player[] player = new Player[2];
public Game21()
{
tokens = 21;
}
public Game21(String player1, String player2, boolean wins, boolean mult)
{
if (mult)
{
multi = mult;
//resetMulti();
}
else
{
tokens = 21;
}
player[0] = new Player(player1);
player[1] = new Player(player2);
lastPlayWins = wins;
}
public Game21(String player1, boolean wins, boolean mult) // computer oppenent
{
if (mult)
{
multi = mult;
//resetMulti();
}
else
{
tokens = 21;
}
player[0] = new Player(player1);
lastPlayWins = wins;
computerOpponent = true;
player[1] = new Player("NIM Bot 2000");
}
public void reset()
{
tokens = 21;
gameOver = false;
}
public void resetMulti(int len)
{
heap = new int[len];
for (int i =0; i<heap.length;i++)
{
heap[i] = rand.nextInt(10) + 1;
}
gameOver= false;
}
public String getWinner()
{
return winner.getName();
}
public int getTokens()
{
return tokens;
}
public boolean isGameOver()
{
return gameOver;
}
public boolean isComputerOpponent()
{
return computerOpponent;
}
public boolean isMulti()
{
return multi;
}
public int findMaxIndex(int[] array)
{
int max = array[0];
int idx = 0;
for(int i = 1; i < array.length; i++)
{
if (max < array[i])
{
max = array[i];
idx = i;
}
}
return idx;
}
public void getComputerMoveMulti()
{
int len = heap.length;
int heapIndex = 0;
int finalTokens = 0;
int finalIndex = 0;
int xor = 0;
for (int i = 0; i < len; i++)
{
xor ^= heap[i];
}
if (xor==0) // no good move, make small random
{
boolean picked = false;
while (!picked)
{
heapIndex = rand.nextInt(len);
if (heap[heapIndex] > 0)
{
finalTokens = rand.nextInt(heap[heapIndex]);
picked = true;
}
}
}
else
{
int[] testHeap = new int[len];
for (int i = 0; i < len; i++)
{
testHeap[i] = heap[i] & xor;
}
heapIndex = findMaxIndex(testHeap);
finalTokens = (heap[heapIndex] - (xor ^ heap[heapIndex]));
}
takeTurnMulti(1, finalTokens, heapIndex);
System.out.println(player[1].getName() + " picks " + finalTokens + " token(s) from heap" + (heapIndex + 1));
}
public String showHeaps()
{
String result = "";
for (int i=0;i<heap.length;i++)
{
result += "Heap " + (i + 1) + " : " + heap[i] + "\t";
}
result += "\n";
return result;
}
public int getComputerMove()
{
int result, best;
if (lastPlayWins)
{
best = tokens % 4;
if (best==0) result = rand.nextInt(3) + 1;
else
{
result = best;
}
}
else
{
best = (tokens % 4) - 1;
if (best < 0) best = 3;
if (best == 0) best = rand.nextInt(3) + 1;
if (tokens <= 4 && tokens < 1) best = tokens - 1;
if (tokens==1) best = 1;
result = best;
}
System.out.println(player[1].getName() + " picks " + result + " token(s).");
return result;
}
public int getOtherPlayer(int n)
{
if (n == 0) return 1;
return 0;
}
public String getPlayer(int n)
{
return player[n].getName();
}
public int getWins(int n)
{
return player[n].getWins();
}
public void takeTurnMulti(int playerNum, int inTokens, int index)
{
if (!gameOver)
{
if (inTokens > heap[index]) inTokens = heap[index];
heap[index] -= inTokens;
int sum = 0;
for (int i=0; i<heap.length;i++) sum += heap[i];
if (sum <= 0)
{
if (lastPlayWins)
{
gameOver = true;
winner = player[playerNum];
player[playerNum].incrementWins();
}
else
{
gameOver = true;
winner = player[getOtherPlayer(playerNum)];
player[getOtherPlayer(playerNum)].incrementWins();
}
}
}
}
public void takeTurn(int playerNum, int inTokens)
{
if (!gameOver)
{
if (inTokens > 3) inTokens = 3;
tokens -= inTokens;
if (tokens <= 0)
{
if (lastPlayWins)
{
gameOver = true;
winner = player[playerNum];
player[playerNum].incrementWins();
}
else
{
gameOver = true;
winner = player[getOtherPlayer(playerNum)];
player[getOtherPlayer(playerNum)].incrementWins();
}
}
}
}
}
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class Nim
{
public static String getInputLine(String prompt)
{
String inString = "";
try
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader ibr = new BufferedReader( isr);
while (inString.equals(""))
{
System.out.print(prompt);
inString = ibr.readLine();
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
return inString;
}
public static void main( String [] args )
{
boolean gameWins = false;
boolean gameMult = false;
int numHeaps = 0;
int turn = 0;
Game21 game;
String player1 = getInputLine("What is your name? ");
String player2 = getInputLine("What is player 2's name, or 'computer' to play against computer? ");
String typeOfGame = getInputLine("What type of game would you like to play?\n (last move wins. type 'W', last move loses, type 'L') ");
String mult = getInputLine("Game style ('M' = multiple heaps; 'T' = 21)? ");
if (typeOfGame.equalsIgnoreCase("w"))
{
gameWins = true;
}
if (mult.equalsIgnoreCase("m"))
{
gameMult = true;
}
if (player2.equalsIgnoreCase("computer"))
{
game = new Game21(player1,gameWins, gameMult);
}
else
{
game = new Game21(player1, player2, gameWins, gameMult);
}
int tokens = 0;
int heap = 0;
int numRounds = Integer.parseInt(getInputLine("Enter number of rounds to play: "));
if (game.isMulti())
{
numHeaps = Integer.parseInt(getInputLine("Enter number of heaps (piles) from 2..n? "));
game.resetMulti(numHeaps);
}
for (int i = 0; i < numRounds; i++)
{
turn = i%2;
System.out.println("========================GAME # " + (i+1) + "======================");
while (!game.isGameOver())
{
if (game.isMulti())
{
System.out.println(game.showHeaps());
if (!game.isComputerOpponent() || turn==0)
{
tokens = Integer.parseInt(getInputLine(game.getPlayer(turn) + ", how many tokens do you take? "));
heap = (Integer.parseInt(getInputLine("From what heap:"))) - 1;
game.takeTurnMulti(turn, tokens, heap);
}
else
{
game.getComputerMoveMulti();
}
turn++;
if (turn > 1) turn = 0;
}
else
{
System.out.println("TOKENS LEFT: " + game.getTokens());
if (!game.isComputerOpponent() || turn==0)
{
tokens = Integer.parseInt(getInputLine(game.getPlayer(turn) + ", how many tokens do you take? "));
}
else
{
tokens = game.getComputerMove();
}
game.takeTurn(turn, tokens);
turn++;
if (turn > 1) turn = 0;
}
}
System.out.println(game.getWinner() + " IS THE WINNER!!!============================");
if (game.isMulti())
{
game.resetMulti(numHeaps);
}
else game.reset();
}
System.out.println("Player 1:" + game.getPlayer(0) + "\t\t\tWins:" + game.getWins(0));
System.out.println("Player 2:" + game.getPlayer(1) + "\t\t\tWins:" + game.getWins(1));
}
}
public class Player
{
private String name;
private int wins;
public Player(String pname)
{
name = pname;
}
public String getName()
{
return name;
}
public void incrementWins()
{
wins++;
}
public int getWins()
{
return wins;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment