lab19
subdirectory of your personal repo, the other submits a file report.txt
in the lab19
subdirectory of your personal repo.Pile of pebbles. Each player can take either one or two pebbles. A player wins if only one pebble is left after their turn.
class AbstractGame<Position> { public abstract boolean win(Position pos); public abstract List<Position> move(Position pos); public Position winningMove(Position pos) { ... } }It turns out you can write a
winningMove
method by calling the win
and move
methods just so.class AbstractGame { winningMove(pos) { for (const n of this.move(pos)) { if (this.losingPosition(n)) return n // Can force the opponent to lose } return undefined // Couldn't find a winning move } losingPosition(pos) { if (this.win(pos)) return true // Just lost for (const n of this.move(pos)) { if (this.winningMove(n) === undefined) return false // Not losing here } return true // Lose no matter what } }
winningMove
and losingPosition
methods figure out what they are?class PebbleGame extends AbstractGame { move(p) { if (p > 2) return [p - 2, p - 1] else if (p === 2) return [1] else return [] } win(p) { return p === 1 } }
const myGame = new PebbleGame() for (let p = 1; p <= 20; p++) { console.log(p + ' -> ' + myGame.winningMove(p)) }Put it all in a file
lab19/nim.js
and run node nim.js
in the cs151/lab19
directory.class NimGame extends AbstractGame { move(p) { const result = [] for (let i = p - 1; 2 * i >= p; i--) result.push(i) return result } win(p) { return p === 1 } }Should you play with 16 pebbles? When should you not play?
extends
. Let's say you are a believer. Which other design pattern could you use to analyze the positions of a game?GameAnalyzer
with methods winningMove
, losingPosition
. It doesn't extend anything, and nothing extends it. In the constructor, provide an object with
move
and win
methods.winningMove
and losingPosition
results. How do you get a hash table? Just use a JavaScript object!GameAnalyzer
. In Java, you could have written the same, but it would have been much harder to describe the types. In Nim, a position is an integer, but in TicTacToe, it's a 3x3 array of strings. So, you'd have to use generic types:
public class GameAnalyzer<PositionType> { public GameAnalyzer(Game<PositionType> game) { ... } // Or maybe <? extends PositionType>? Or super??? public List<PositionType> winningMove(PositionType pos) { ... } ... }It's more robust, of course, but also more work.