aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/server/old/human_game.py
blob: dbf1f61b1f3b2a591fa01bcd852010e0690e01fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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)