aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/server/toggle_game.py
diff options
context:
space:
mode:
authorJean-Pierre Appel <jeanpierre.appel01@gmail.com>2023-10-23 01:34:33 -0400
committerJean-Pierre Appel <jeanpierre.appel01@gmail.com>2023-10-23 01:34:33 -0400
commit424be4138123e7d8e2e9fef36c71e1638d4e6b2a (patch)
treebc7339af6966ff78fd3ee7fbfe05c4e7974bb256 /server/toggle_game.py
parent7815a927374db87393d104d095b5de8dfd3a3488 (diff)
testing wsgi post
Diffstat (limited to 'server/toggle_game.py')
-rw-r--r--server/toggle_game.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/server/toggle_game.py b/server/toggle_game.py
new file mode 100644
index 0000000..7932de9
--- /dev/null
+++ b/server/toggle_game.py
@@ -0,0 +1,134 @@
+from fast_P_nim import P
+
+
+def safe_int_parse(s):
+ try:
+ return int(s)
+ except ValueError:
+ return -1
+
+
+def display_game(game: dict) -> None:
+ for i in range(game['size']):
+ if game['board'][i]:
+ print(f'{i+1:02d}', end="")
+ else:
+ print(' ', end="")
+ if i + 1 != game['size']:
+ print('-', end="")
+ print()
+
+
+def valid_move(game: dict, i: int):
+ if i >= game['size'] or i < 0:
+ return False
+ if game['board'][i]:
+ if i > 0:
+ if i < game['size']-1:
+ return game['board'][i-1] or game['board'][i+1]
+ else:
+ return game['board'][i-1]
+ else:
+ if i < game['size']-1:
+ return game['board'][i+1]
+ else:
+ return True
+
+
+def make_move(game: dict, i: int):
+ gs = game['board'].copy()
+ gs[i] = False
+ if i > 0:
+ gs[i-1] = not gs[i-1]
+ if i < game['size']-1:
+ gs[i+1] = not gs[i+1]
+ return gs
+
+
+def get_nimber(gs: list) -> int:
+ n = len(gs)
+ nimber_so_far = 0
+ path_size = 0
+ for i in range(n):
+ if gs[i]:
+ path_size += 1
+ else:
+ if path_size == 1 and n != 1:
+ path_size = 0
+ nimber_so_far = nimber_so_far ^ P(path_size)
+ path_size = 0
+ if path_size == 1 and n != 1:
+ path_size = 0
+ nimber_so_far = nimber_so_far ^ P(path_size)
+ return nimber_so_far
+
+
+def i_have_won(game: dict) -> bool:
+ for i in range(game['size']):
+ if valid_move(game, i):
+ return False
+ return True
+
+
+def find_move(game: dict) -> int:
+ game_state_orig = game['board'].copy()
+ for i in range(game['size']):
+ if valid_move(game, i):
+ gs = make_move(game, i)
+ if get_nimber(gs) == 0:
+ return i
+ raise Exception("I have been beat!")
+
+
+def new_game(size: int) -> dict:
+ game = {}
+ game['board'] = [True] * size
+ game['human_turn'] = not P(size) > 0
+ game['size'] = size
+ game['version'] = '0.0.0'
+ game['finished'] = False
+ game['winner'] = ""
+ game['turn'] = 1
+ return game
+
+
+def main():
+ n = int(input("Path size to play on> "))
+ game = new_game(n)
+
+ if game['human_turn']:
+ print("You can play first!")
+ else:
+ print("I'll play first!")
+
+ while True:
+ display_game(game)
+ if game['human_turn']:
+ if i_have_won(game):
+ print("You're out of moves. I win!")
+ game['finished'] = True
+ game['winner'] = "Computer"
+ break
+ game['human_turn'] = False
+ i = -1 # placeholder
+ while True:
+ i = safe_int_parse(input("Make your move> ")) - 1
+ if valid_move(game, i):
+ break
+ print("Hey! That's not allowed!")
+ display_game(game)
+ game['turn'] += 1
+ game['board'] = make_move(game, i)
+ else:
+ game['human_turn'] = True
+ i = find_move(game)
+ print(f"Hmm... I'll toggle {i + 1}")
+ game['turn'] += 1
+ game['board'] = make_move(game, i)
+
+ print('-'*8)
+ for key, val in game.items():
+ print(f'{key}: {val}')
+
+if __name__ == "__main__":
+ main()