Select Git revision
-
Brady James Garvin authoredBrady James Garvin authored
nim.py 3.01 KiB
#! /usr/bin/python
from __future__ import division, print_function
from enum import Enum
from copy import copy
from random import randrange
class Evaluation(Enum):
LOSS = 'LOSS'
WIN = 'WIN'
def convert_to_single_heap_using_builtin(heap_a, heap_b):
"""
Convert a pair of Nim heap sizes to the size of an equivalent single heap.
Python happens to have an operator (^) that works exactly as we need it to.
"""
return heap_a ^ heap_b
def convert_to_single_heap_recursively(heap_a, heap_b):
"""
Convert a pair of Nim heap sizes to the size of an equivalent single heap.
This time, use recursion.
>>> convert_to_single_heap_recursively(0, 0)
0
>>> convert_to_single_heap_recursively(5, 0)
5
>>> convert_to_single_heap_recursively(0, 5)
5
>>> convert_to_single_heap_recursively(5, 6)
3
>>> convert_to_single_heap_recursively(9, 5)
12
>>> convert_to_single_heap_recursively(21, 10)
31
>>> convert_to_single_heap_recursively(21, 11)
30
"""
return 0 # Stub
def evaluate(heap_sizes):
"""
Evaluate a Nim position given as a list of heap sizes, returning
Evaluation.LOSS if the player who just moved will lose under perfect play,
Evaluation.WIN if the player who just moved will win under perfect play.
>>> evaluate([])
<Evaluation.WIN: 'WIN'>
>>> evaluate([0])
<Evaluation.WIN: 'WIN'>
>>> evaluate([1])
<Evaluation.LOSS: 'LOSS'>
>>> evaluate([0, 1])
<Evaluation.LOSS: 'LOSS'>
>>> evaluate([1, 1])
<Evaluation.WIN: 'WIN'>
>>> evaluate([1, 2, 2])
<Evaluation.LOSS: 'LOSS'>
>>> evaluate([3, 2, 1])
<Evaluation.WIN: 'WIN'>
>>> evaluate([9, 12, 3, 6])
<Evaluation.WIN: 'WIN'>
>>> evaluate([9, 12, 3, 7])
<Evaluation.LOSS: 'LOSS'>
"""
return Evaluation.LOSS # Stub
def make_computer_move(position):
"""
Return a Nim position after the computer has made a move from the position
given.
"""
for i, heap_size in enumerate(position):
next_position = copy(position)
for j in range(heap_size):
next_position[i] = j
if evaluate(next_position) is Evaluation.WIN:
return next_position
return next_position
def main():
"""
A simple command-line Nim game with no error handling.
"""
position = [randrange(1, 10) for _ in range(randrange(3, 7))]
while True:
print('Heaps: {position}'.format(position=position))
if sum(position) == 0:
print('Human Wins!')
print()
return
print('Computer moves...')
print()
position = make_computer_move(position)
print('Heaps: {position}'.format(position=position))
if sum(position) == 0:
print('Computer Wins!')
print()
return
index = int(input('Index at which to take stones? '))
count = int(input('Number of stones to take? '))
print()
position[index] -= count
if __name__ == '__main__':
main()