As an attempt to pick up the basics of python I decided to try and recreate nim sticks in python 3. I'm using pyCharm for this development.
When the AI player checks for what sticks to remove the lines
variable in the game_ai
function appears to overwrite itself for no apparent reason.
main.py:
import ai
import helpers
lines = [1, 3, 5, 7]
winner = 0
# String introduction
print(' _____ _ _ _ ')
print(' / ____| | (_) | | ')
print(' | (___ | |_ _ ___| | _____ ')
print(' \___ \| __| |/ __| |/ / __| ')
print(' ____) | |_| | (__| <\__ \ ')
print(' |_____/ \__|_|\___|_|\_\___/ ')
print('The last one to pick up a stick loses!')
# Keep going till we have a winner!
while winner == 0:
# Redraw the stick board at the start of a turn
helpers.redraw_sticks(lines)
# Get user input and remove their sticks
line = helpers.check_input('Please select a line to remove (a) stick(s) from:', 0, 4, 'line', lines)
amount = helpers.check_input('Please select how many stick(s) you wish to remove:', 0, 7, 'amount', lines)
lines = helpers.remove_sticks(lines, line, amount)
# Check for winner
winner = helpers.winner_check(lines, 1)
# Only play the AI if the player doesn't win this go
if winner == 0:
# Redraw the board after a go
helpers.redraw_sticks(lines)
# Play the AI
ai_turn = ai.game_ai(lines)
lines = helpers.remove_sticks(lines, ai_turn[0], ai_turn[1] - 1)
# Check for winner
winner = helpers.winner_check(lines, 2)
# Declare the winner!
if winner == 1:
print('The Human Player wins the game!')
else:
print('The Computer Player wins the game!')
ai.py:
import helpers
import time
# Our cool kid AI
def game_ai(lines):
winning_data = [0, 0]
winning_combo = False
# Keep going till we get a winning nim sum
while not winning_combo:
line = 1
# Go through every line
while line <= 4 and not winning_combo:
# Reset amount value
amount = 7
# Make it look like there's actual heavy processing going on here
print('AI player is thinking...')
time.sleep(1)
# Only go if the line actually has sticks
if lines[line - 1] != 0:
# Test certain values in a line
while amount >= 1 and not winning_combo:
lines_test = helpers.remove_sticks(lines, line, amount)
# If we have a nim sum of 0 we go!
if helpers.nim_sum(lines_test) == 0:
winning_combo = True
winning_data[0] = line
winning_data[1] = amount
# I'm going to win, I shouldn't do this...
if helpers.lines_checksum(lines_test) == 0:
winning_data[1] = amount - 1
# Increment amount
amount -= 1
# Increment line
line += 1
# Return winning data
return winning_data
helpers.py:
import sys
# Redraws the stick board with updated values
def redraw_sticks(lines):
# Loop through each line
for (line, sticks) in enumerate(lines):
if sticks > 0:
# Output line number
sys.stdout.write(str(line + 1) + ': ')
# And output how many sticks there are
for x in range(0, sticks):
sys.stdout.write('|')
print('')
# Remove sticks on request
def remove_sticks(lines, line, amount):
# Set line to the correct pointer
line -= 1
if lines[line] < amount:
lines[line] = 0
else:
lines[line] = lines[line] - amount
return lines
# Check if an input is an integer and in the correct range
def check_input(request_message, min_value, max_value, check_type, lines):
inputting = True
user_input = 0
while inputting:
user_input = input(request_message)
try:
# Check if the input is an integer
user_input = int(user_input)
# Make sure the input fits in our defined range
if max_value >= user_input > min_value:
inputting = False
# Check if the line has any sticks left
if check_type == 'line' and lines[user_input - 1] <= 0:
print('Error: Line is already empty')
inputting = True
else:
print('Error: Invalid range value entered')
except ValueError:
print('Error: String input entered')
# Return the input after checks
return user_input
def nim_sum(lines):
# First we need to calculate the multiples
nim_sum_total = 0
for (pointer, sticks) in enumerate(lines):
# Calculate multiples of 4
nim_sum_total += sticks // 4
sticks %= 4
# Calculate multiples of 2
nim_sum_total += sticks // 2
sticks %= 2
# Calculate multiples of 1
nim_sum_total += sticks // 1
return nim_sum_total % 2
# Check how many sticks are left
def lines_checksum(lines):
checksum = 0
# Calculate remaining sticks
for sticks in lines:
checksum += sticks
return checksum
# Check if a winner has been found
def winner_check(lines, player):
checksum = lines_checksum(lines)
# Return if we have a winner
if checksum == 1:
return player
else:
return 0