Skip to content

Commit f51e5aa

Browse files
committed
Bot recognizes a draw
1 parent e8aee8b commit f51e5aa

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

bot/player.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,21 @@ def _transfer_stake(hex_message, multiplier=1):
4848
return coder.increment_state_balance(hex_message, 1, multiplier * stake)
4949

5050

51-
def stake_move(hex_message):
51+
def check_end_of_game(hex_message):
52+
if strategy.check_win(hex_message):
53+
hex_message = coder.update_game_position(hex_message, 3)
54+
return transfer_double_stake(hex_message)
55+
if strategy.check_draw(hex_message):
56+
hex_message = coder.update_game_position(hex_message, 4)
57+
return transfer_stake(hex_message)
58+
return transfer_double_stake(hex_message)
59+
60+
61+
def transfer_double_stake(hex_message):
5262
return _transfer_stake(hex_message, 2)
5363

5464

55-
def stake_first_move(hex_message):
65+
def transfer_stake(hex_message):
5666
return _transfer_stake(hex_message)
5767

5868

@@ -67,19 +77,18 @@ def play_cross_move(hex_message):
6777
crosses = coder.get_game_crosses(hex_message) + move
6878
return coder.update_crosses(hex_message, crosses)
6979

70-
# Need to fix stake
71-
7280

7381
def from_resting(_hex_message):
74-
return [coder.update_noughts, stake_first_move, play_cross_move, coder.change_game_position]
82+
return [coder.update_noughts, transfer_stake, play_cross_move, coder.change_game_position]
7583

7684

7785
def from_oplay(_hex_message):
78-
return [stake_move, play_cross_move, lambda h_message: coder.change_game_position(h_message, -1)]
86+
return [play_cross_move,
87+
lambda h_message: coder.change_game_position(h_message, -1), check_end_of_game]
7988

8089

8190
def from_xplay(_hex_message):
82-
return [stake_move, play_nought_move, coder.change_game_position]
91+
return [play_nought_move, coder.change_game_position, check_end_of_game]
8392

8493

8594
def from_victory(hex_message):
@@ -89,12 +98,16 @@ def from_victory(hex_message):
8998
return [coder.new_game]
9099

91100

101+
def from_draw(_hex_message):
102+
return [coder.new_game]
103+
104+
92105
GAME_STATES = (
93106
from_resting,
94107
from_xplay,
95108
from_oplay,
96109
from_victory,
97-
lambda x: undefined_game_position('FromDraw'),
110+
from_draw,
98111
)
99112

100113

bot/strategy.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
64, 128, 256,
88
]
99

10+
WINNING_POSITIONS = [448, 56, 7, 292, 146, 73, 273, 84]
11+
DRAW = 511
12+
1013

1114
def next_move(hex_message):
1215
noughts = get_game_noughts(hex_message)
@@ -16,3 +19,19 @@ def next_move(hex_message):
1619
move = VALID_MOVES[random.randint(0, 8)]
1720
if noughts | move != noughts and crosses | move != crosses:
1821
return move
22+
23+
24+
def check_win(hex_message):
25+
noughts = get_game_noughts(hex_message)
26+
crosses = get_game_crosses(hex_message)
27+
if noughts in WINNING_POSITIONS or crosses in WINNING_POSITIONS:
28+
return True
29+
return False
30+
31+
32+
def check_draw(hex_message):
33+
noughts = get_game_noughts(hex_message)
34+
crosses = get_game_crosses(hex_message)
35+
if noughts + crosses == DRAW:
36+
return True
37+
return False

test/test_app.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,33 @@ def test_black_box_from_victory(test_app):
106106
state_machine_transition(state, new_state)
107107

108108

109+
def test_black_box_from_draw(test_app, mocker):
110+
with test_app.test_request_context('channel_message'):
111+
mocker.patch('random.randint', lambda _x, _y: 2)
112+
state = '0000000000000000000000006251cac0089a95826b375f9e4d8638b8d472eee400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000002000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F00000000000000000000000055de2e479f3d0183d95f5a969beeb3a147f600490000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000000009c0000000000000000000000000000000000000000000000000000000000000163'
113+
new_state = '0000000000000000000000006251cac0089a95826b375f9e4d8638b8d472eee400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000002000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F00000000000000000000000055de2e479f3d0183d95f5a969beeb3a147f600490000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000'
114+
state_machine_transition(state, new_state)
115+
116+
109117
def test_black_box_from_resting(test_app, mocker):
110118
with test_app.test_request_context('channel_message'):
111119
mocker.patch('random.randint', lambda _x, _y: 0)
112120
state = '00000000000000000000000007f96aa816c1f244cbc6ef114bb2b023ba54a2eb000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000020000000000000000000000001251659F5A4897bBebeB949E6Df22697d43C42dC000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044364c5bb00000000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5e620f48000'
113121
new_state = '00000000000000000000000007f96aa816c1f244cbc6ef114bb2b023ba54a2eb000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000020000000000000000000000001251659F5A4897bBebeB949E6Df22697d43C42dC000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'
114122
state_machine_transition(state, new_state)
123+
124+
125+
def test_black_box_to_bot_win(test_app, mocker):
126+
with test_app.test_request_context('channel_message'):
127+
mocker.patch('random.randint', lambda _x, _y: 2)
128+
state = '00000000000000000000000007f96aa816c1f244cbc6ef114bb2b023ba54a2eb000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000020000000000000000000000001251659F5A4897bBebeB949E6Df22697d43C42dC000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d79883d2000000000000000000000000000000000000000000000000000000044364c5bb000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000120'
129+
new_state = '00000000000000000000000007f96aa816c1f244cbc6ef114bb2b023ba54a2eb000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000020000000000000000000000001251659F5A4897bBebeB949E6Df22697d43C42dC000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016bcc41e900000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000124'
130+
state_machine_transition(state, new_state)
131+
132+
133+
def test_black_box_to_bot_draw(test_app, mocker):
134+
with test_app.test_request_context('channel_message'):
135+
mocker.patch('random.randint', lambda _x, _y: 1)
136+
state = '0000000000000000000000006251cac0089a95826b375f9e4d8638b8d472eee400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000002000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F00000000000000000000000055de2e479f3d0183d95f5a969beeb3a147f60049000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001550f7dca70000000000000000000000000000000000000000000000000000000e35fa931a0000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000014c'
137+
new_state = '0000000000000000000000006251cac0089a95826b375f9e4d8638b8d472eee400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000002000000000000000000000000A317E78f9F62Bc4959D0682F30043B9C0797C74F00000000000000000000000055de2e479f3d0183d95f5a969beeb3a147f600490000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000014e'
138+
state_machine_transition(state, new_state)

0 commit comments

Comments
 (0)