aboutsummaryrefslogtreecommitdiff
path: root/api/game/voerbak_connector.py
blob: 0b51bd56b1a1047b74bc1a3bb42af92679b78d8e (plain)
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
from colorama import Fore
import log
import subprocess
import os

DISC_SHAPE = "o"
DISC_A = Fore.RED + DISC_SHAPE + Fore.RESET
DISC_B = Fore.BLUE + DISC_SHAPE + Fore.RESET
EMPTY = Fore.LIGHTBLACK_EX + "_" + Fore.RESET

VOERBAK_LOCATION = os.path.join(os.getcwd(), "voerbak/", "voerbak")
if os.name == "nt": VOERBAK_LOCATION += ".exe"


class bord:
	def __init__(self, w, h):
		self.width = w
		self.height = h
		self.player_1 = True
		self.board = "0" * (w * h)
		self.board_full = False
		self.win_positions = []
		self.process = subprocess.Popen(
			[VOERBAK_LOCATION, f"-w {w}", f"-h {h}"],
			stdin=subprocess.PIPE,
			stdout=subprocess.PIPE,
			stderr=None
		)
		self.process.stdin.flush()

	# get output from voerbak without trailing newline character (this might break on windows because crlf)
	def get_output(self):
		return self.process.stdout.readline().decode()[:-1]

	def kill_voerbak(self):
		self.process.stdin.write(bytearray("0", "utf-8"))
		self.process.stdin.flush()

	# read messages from voerbak
	def update_board(self):
		buffer = self.get_output()
		while not buffer.isdigit():
			# win message
			if buffer.startswith("w:"):
				self.win_positions.append(buffer[2:].split("-"))
				log.info(f"won: {buffer[2:].split('-')}")
				self.kill_voerbak()
			# error message
			elif buffer.startswith("e:"):
				log.warning(buffer[2:])
			# turn update message
			elif buffer.startswith("m:"):
				substr = buffer[2:]
				self.player_1 = True if substr == "true" else False
			# draw game message
			elif buffer.startswith("d:"):
				self.board_full = True
				self.kill_voerbak()
			buffer = self.get_output()
		self.board = buffer

	# debug board print function
	def print(self):
		for y in range(self.height - 1, -1, -1):
			for x in range(self.width):
				state = self.board[x + y * self.width]
				char = [EMPTY, DISC_A, DISC_B]
				print(char[int(state)], end="  ")
			print("\n", end="")

	def drop_fisje(self, column):
		self.process.stdin.write(bytearray(f"{column}\n", "utf-8"))
		self.process.stdin.flush()
		self.update_board()


# debug game
def main():
	gert = bord(7, 6)
	while True:
		print(gert.player_1)
		if len(gert.win_positions) > 0:
			print(f"won: {gert.win_positions}")
			exit(0)
		gert.print()
		column = int(input("column?: ")) - 1
		if column not in range(gert.width):
			continue
		gert.drop_fisje(column + 1)


if __name__ == "__main__":
	main()