/** * Represents the game (ruleset) Wythoff's Nim. * * @author Kyle Burke <paithanq@gmail.com> * */ //package something; import java.lang.*; import java.io.*; import java.util.*; public class WythoffsNim extends CombinatorialGame { //instance variables private Pair<Integer, Integer> piles; //constants /** Constructors **/ /** * Class Consstructor. * * @param pair A pair of integers representing the sizes of the two piles. Throws an exception if either of the elements of pair is null or negative. * @throws IllegalArgumentException If either elements in the pair is null or negative. Negative numbers are illegal pile sizes. */ public WythoffsNim(Pair<Integer, Integer> piles) { if (piles == null || piles.getFirst() == null || piles.getFirst() < 0 || piles.getSecond() == null || piles.getSecond() < 0) { throw new IllegalArgumentException("Argument cannot be null or have null or negative values!"); } //don't just use the parameter pair; we need a deep copy so it can't be modified from outside. this.piles = new Pair<Integer, Integer>(piles.getFirst(), piles.getSecond()); } //public methods //@override public String toString() { return "Wythoff's Nim (" + this.piles.getFirst() + ", " + this.piles.getSecond() + ")"; } //@override public Collection<CombinatorialGame> getOptions(int player) { Collection<CombinatorialGame> options = new ArrayList<CombinatorialGame>(); int first = this.piles.getFirst(); int second = this.piles.getSecond(); //Get the moves that take from the first pile for (int x = 0; x < first; x++) { options.add(new WythoffsNim(new Pair<Integer, Integer>(x, second))); } //Get the moves that take from the second pile for (int y = 0; y < second; y++) { options.add(new WythoffsNim(new Pair<Integer, Integer>(first, y))); } //Add the moves that take from both piles int min = Math.min(first, second); for (int both = 1; both <= min; both ++) { options.add(new WythoffsNim(new Pair<Integer, Integer>(first - both, second - both))); } return options; } /** * Returns the name of this game. * * @return The String "Wythoff's Nim". */ public static String getName() { return "Wythoff's Nim"; } /** * Returns the piles. * * @return A pair of integers that is a deep copy of the piles here. */ public Pair<Integer, Integer> getPiles() { return new Pair<Integer, Integer>(this.piles.getFirst(), this.piles.getSecond()); } /** * Returns a deep clone of this. * * @return A deep clone of this position. */ public CombinatorialGame clone() { return new WythoffsNim(this.piles); } //@override public boolean equals(Object other) { try { WythoffsNim otherGame = (WythoffsNim) other; return this.equals(otherGame); } catch (ClassCastException cce) { return false; } } //@override public boolean equals(CombinatorialGame other) { try { WythoffsNim otherGame = (WythoffsNim) other; return this.equals(otherGame); } catch (ClassCastException cce) { return false; } } /** * Returns whether this equals another position. * * @param other Another position. * @return Whether this position equals the other. This should compare identity, *NOT* equivalence. */ public boolean equals(WythoffsNim other) { if (this.piles.equals(other.piles)) { return true; } else { return this.piles.equals(other.piles.getReverse()); } } /** * Generator for Wythoff's Nim Games. */ public static class PositionBuilder implements PositionFactory<WythoffsNim> { //maximum initial pile size private int maxPileSize; /** * Constructor * @param maxPileSize The maximum size of a pile. */ public PositionBuilder(int maxPileSize) { this.maxPileSize = maxPileSize; } /** * Generate a position! * * @return A new WythoffsNim position. */ public WythoffsNim getPosition() { Random random = new Random(); int first = random.nextInt(this.maxPileSize + 1); int second = random.nextInt(this.maxPileSize + 1); return new WythoffsNim(new Pair<Integer, Integer>(first, second)); } } //end of WythoffsNim.PositionBuilder /** * Main method for testing. */ public static void main(String[] args) { WythoffsNim nim = new WythoffsNim(new Pair<Integer, Integer>(3, 5)); System.out.println("nim: " + nim); System.out.println("Options for nim: " + nim.getOptions(CombinatorialGame.LEFT)); //test out the Factory PositionFactory<WythoffsNim> factory = new WythoffsNim.PositionBuilder(5); nim = factory.getPosition(); System.out.println("Randomly generated position: " + nim); System.out.println("Another randomly generated position: " + factory.getPosition()); } } //end of WythoffsNim.java