diff options
| author | Jean-Pierre Appel <jeanpierre.appel01@gmail.com> | 2023-10-23 01:34:33 -0400 |
|---|---|---|
| committer | Jean-Pierre Appel <jeanpierre.appel01@gmail.com> | 2023-10-23 01:34:33 -0400 |
| commit | 424be4138123e7d8e2e9fef36c71e1638d4e6b2a (patch) | |
| tree | bc7339af6966ff78fd3ee7fbfe05c4e7974bb256 /server | |
| parent | 7815a927374db87393d104d095b5de8dfd3a3488 (diff) | |
testing wsgi post
Diffstat (limited to 'server')
| -rw-r--r-- | server/.gitignore | 3 | ||||
| -rw-r--r-- | server/fast_p_sage.py | 35 | ||||
| -rw-r--r-- | server/old/fast_P_nim.py | 41 | ||||
| -rw-r--r-- | server/old/human_game.py | 115 | ||||
| -rw-r--r-- | server/server.py | 42 | ||||
| -rw-r--r-- | server/toggle_game.py | 134 |
6 files changed, 370 insertions, 0 deletions
diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..cfd027d --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +__py_cache +.venv diff --git a/server/fast_p_sage.py b/server/fast_p_sage.py new file mode 100644 index 0000000..54902ad --- /dev/null +++ b/server/fast_p_sage.py @@ -0,0 +1,35 @@ +hashStuff = {0: 0, 1: 1, 2: 1, 3: 1, 4: 2, 5: 2} + + +def MEX(S: set) -> int: + i = 0 + while True: + if i not in S: + return i + i += 1 + + +def P(n: int) -> int: + """ + Compute nimber for a path of a certain length + """ + if n in hashStuff: + return hashStuff[n] + res = Prec(n) + hashStuff[n] = res + return res + + +def Prec(n: int) -> int: + S = set() + # Works only for n >= 5 + S.add(P(n-2)) + S.add(P(n-3)) + S.add(P(n-4)) + for i in range(2, n-5+1): + S.add(nimAdd(P(i), P(n-3-i))) + return MEX(S) + + +def nimAdd(x: int, y: int) -> int: + return x ^ y diff --git a/server/old/fast_P_nim.py b/server/old/fast_P_nim.py new file mode 100644 index 0000000..adafca1 --- /dev/null +++ b/server/old/fast_P_nim.py @@ -0,0 +1,41 @@ +hashStuff = {0: 0, 1: 1, 2: 1, 3: 1, 4: 2, 5: 2} + +def MEX(S): + i = 0 + while True: + if i not in S: + return i + i += 1 + +def P(n): + if n in hashStuff: + return hashStuff[n] + res = Prec(n) + hashStuff[n] = res + return res + +def Prec(n): + S = set() + # Works only for n >= 5 + S.add(P(n-2)) + S.add(P(n-3)) + S.add(P(n-4)) + for i in range(2,n-5+1): + S.add(nimAdd(P(i),P(n-3-i))) + return MEX(S) + +def nimAdd(x, y): + return x ^ y + +# P(7) +# for i in range(1,1000): +# print(f"Path, n={i} (oeis={i-1}): {P(i)}") + +# Pgames = set() +# for i in range(20000): +# if hashStuff[i] == 0: +# Pgames.add(i) + +# for i in range(200): +# print(i, P(1000*i)) + diff --git a/server/old/human_game.py b/server/old/human_game.py new file mode 100644 index 0000000..dbf1f61 --- /dev/null +++ b/server/old/human_game.py @@ -0,0 +1,115 @@ +from fast_P_nim import P + +def safe_int_parse(s): + try: + return int(s) + except ValueError: + return -1 + +n = int(input("Path size to play on> ")) + +nimb = P(n) + +human_turn = -1 # placeholder +if nimb > 0: + human_turn = False + print("I'll play first!") +else: + human_turn = True + print("You can play first!") + +game_state = [True for _ in range(n)] + +def display_game(): + for i in range(n): + if game_state[i]: + print(f'{i+1:02d}', end="") + else: + print(f' ', end="") + if i + 1 != n: + print('-', end="") + print() + +def valid_move(i): + if i >= n or i < 0: + return False + if game_state[i]: + if i > 0: + if i < n-1: + return game_state[i-1] or game_state[i+1] + else: + return game_state[i-1] + else: + if i < n-1: + return game_state[i+1] + else: + return True + +def make_move(i): + gs = game_state.copy() + gs[i] = False + if i > 0: + gs[i-1] = not gs[i-1] + if i < n-1: + gs[i+1] = not gs[i+1] + return gs + +def get_nimber(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(): + for i in range(n): + if valid_move(i): + return False + return True + +def find_move(): + game_state_orig = game_state.copy() + for i in range(n): + if valid_move(i): + gs = make_move(i) + if get_nimber(gs) == 0: + return i + raise Exception("I have been beat!") + +# game_state = make_move(2-1) +# game_state = make_move(6-1) +# game_state = make_move(6-1) +# display_game() +# print(get_nimber(game_state)) +# raise Exception() + +while True: + display_game() + if human_turn: + if i_have_won(): + print("You're out of moves. I win!") + break + human_turn = False + i = -1 # placeholder + while True: + i = safe_int_parse(input("Make your move> ")) - 1 + if valid_move(i): + break + print("Hey! That's not allowed!") + display_game() + game_state = make_move(i) + else: + human_turn = True + i = find_move() + print(f"Hmm... I'll toggle {i + 1}") + game_state = make_move(i) + diff --git a/server/server.py b/server/server.py new file mode 100644 index 0000000..9f04e4e --- /dev/null +++ b/server/server.py @@ -0,0 +1,42 @@ +import json +import toggle_game + + +def recieve_game(game_json: str) -> dict: + game = json.loads(game_json) + if game['size'] < 0 or game['size'] > 100: + raise Exception("Invalid Board size") + if game['finished']: + raise Exception("The game is finished") + if game['human_turn']: + raise Exception("Not the computer's turn") + if game['version'] != "0.0.0": + raise Exception("Invalid version") + return game + + +def send_game(game: dict) -> str: + # TODO: mutate game + game_json = json.dumps(game) + return game_json + + +def application(env, start_response): + headers = [('Content-Type', 'application/json')] + start_response('200 OK', headers) + + if env['REQUEST_METHOD'] == 'POST': + game = {'test': 0} + try: + game = json.load(env['wsgi.input']) + except json.JSONDecodeError: + return [json.dumps({'failure': True}).encode('utf-8')] + game_json = json.dumps(game) + return [game_json.encode('utf-8')] + + return [json.dumps({'not_post': True}).encode('utf-8')] + + + +def main(): + pass 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() |
