Bendzove_Piskvorky/server.py

234 lines
9.1 KiB
Python

import asyncio
import json
import random
import websockets
import threading
width = 10
height = 6
player_on_turn = 0
grid = []
connected = set()
cache = [{"player": 0, "col": -1}]
async def socket_broadcast(data):
for client in connected:
await client.send(str(data))
players = []
async def hello(ws, _):
global cache
global width
global height
global player_on_turn
exitit = 0
connected.add(ws)
this_id = random.randint(0, 100000)
i = 0
players.append({"ws": ws, "id": this_id})
if len(players) >= 3:
await socket_broadcast(json.dumps({"action": "print", "data": f"Warning {len(players)} players are connected"}))
await ws.send(json.dumps({"action": "id", "id": this_id}))
try:
await ws.send(await draw(grid, True))
for player in players:
if player["ws"] == ws:
await ws.send(json.dumps({"action": "print", "data": f"It is your turn, type 'add (number of column from 0 to {width - 1})' :"}))
else:
ws.send(json.dumps({"action": "print", "data": f"It is player{player_on_turn} 's turn."}))
await ws.send(json.dumps({"action": "print", "data": "Enter command:"}))
while exitit == 0:
try:
x = await ws.recv()
try:
temp2 = json.loads(x)
print(str(temp2))
cmd_args = str(temp2["action"]).split(" ")
temp = {"action": cmd_args[0], "args": [], "id": temp2["id"]}
i = 0
for cmd_arg in cmd_args:
if i != 0:
temp["args"].append(cmd_arg)
i = i + 1
print(str(temp))
if str(temp["action"]) == "reset":
await reset()
await draw(grid)
await socket_broadcast(
json.dumps({"action": "print", "data": f"It is player{player_on_turn} 's turn."}))
await players[player_on_turn]['ws'].send(json.dumps(
{"action": "print",
"data": f"It is your turn, input column number from 0 to {width - 1}:"}))
elif str(temp["action"]) == "redraw":
await ws.send(await draw(grid, True))
elif str(temp["action"]) == "resize":
try:
if len(temp["args"]) >= 2:
width = int(temp["args"][0])
height = int(temp["args"][1])
await reset()
await ws.send(await draw(grid, True))
await socket_broadcast(
json.dumps({"action": "print", "data": f"It is player{player_on_turn} 's turn."}))
await players[player_on_turn]['ws'].send(json.dumps({"action": "print",
"data": f"It is your turn, type 'add (number of column from 0 to {width - 1})' :"}))
except ValueError:
await ws.send(json.dumps({"action": "print", "data": "Invalid arguments to resize."}))
elif str(temp["action"]) == "add":
if len(temp["args"]) >= 1:
plx = 0
for player in players:
if int(temp["id"]) == int(player["id"]):
if plx == player_on_turn:
res = await add(grid, temp["args"][0])
if res == 1:
await apply_gravity(grid)
await socket_broadcast(await draw(grid, True))
await socket_broadcast(json.dumps(
{"action": "print", "data": f"It is player{player_on_turn} 's turn."}))
await players[player_on_turn]['ws'].send(json.dumps({"action": "print",
"data": f"It is your turn, input 'add (0 to {width - 1})':"}))
elif res == 2:
await players[player_on_turn]['ws'].send(json.dumps({"action": "print",
"data": f"Oops you have entered '{temp['col']}' which is not a valid input. Please try again player{player_on_turn}:"}))
elif res == 0:
await players[player_on_turn]['ws'].send(json.dumps({"action": "print",
"data": f"Oops you have entered '{temp['col']}' which is full. Please try again player{player_on_turn}:"}))
plx = plx + 1
elif str(temp["action"]) == "version":
await ws.send(json.dumps(
{"action": "print",
"data": "Bendžove Piškvorky\n'Jeminé, Bruno nemáš tam algorytmus' edition"}))
elif str(temp["action"]) == "help":
await ws.send(json.dumps({"action": "print",
"data": f"\n'reset' - Resets the game\n'redraw' - Sends you the current state of the board\n'resize' - Resizes the playing board and resets it usage: 'resize (width) (height)'\n'add' - Adds your character to a column, usage: 'add (column number from 0 to {width - 1})\n'version' - Prints version of the server\n'help' - Prints this help message"}))
else:
await ws.send(json.dumps(
{"action": "print", "data": "Unknown command. Type 'help' to list all commands."}))
await ws.send(json.dumps({"action": "print", "data": "Enter command:"}))
except Exception as e:
print(e)
except Exception as e:
print(e)
connected.remove(ws)
exitit = 1
finally:
# Unregister.
try:
connected.remove(ws)
i = 0
for x in players:
if x[ws] == ws:
players.pop(i)
i = i + 1
except Exception as e:
print(e)
async def reset():
global grid
grid = []
for _ in range(width):
temp_grid = []
for _ in range(height):
temp_grid.append(" ")
grid.append(temp_grid)
async def apply_gravity(gridx):
for gr in gridx:
for _ in range(height):
for i in range(height - 2, -1, -1):
if gr[i] == "X" and gr[i + 1] == " ":
gr[i + 1] = "X"
gr[i] = " "
if gr[i] == "O" and gr[i + 1] == " ":
gr[i + 1] = "O"
gr[i] = " "
if gr[i] == "X" and gr[i + 1] == " ":
gr[i + 1] = "X"
gr[i] = " "
if gr[i] == "O" and gr[i + 1] == " ":
gr[i + 1] = "O"
gr[i] = " "
async def add(gridx, col3):
try:
col = int(col3)
except ValueError:
return 2
if -1 < col < width:
global player_on_turn
if gridx[col][0] == " ":
if player_on_turn == 1:
gridx[col][0] = "O"
player_on_turn = 0
return 1
else:
gridx[col][0] = "X"
player_on_turn = 1
return 1
else:
return 0
return 2
async def draw(gridx, return_data=False):
tmp = ""
for i in range((width * 4) - 7):
tmp = tmp + ""
tmp = tmp + "\n/"
for i in range((width * 2) - 1):
tmp = tmp + " "
tmp = tmp + "\\"
tmp = tmp + "\n"
for i in range(0, width):
tmp = tmp + f"{i}"
tmp = tmp + "\n"
for y in range(0, height):
for x in range(0, width):
tmp = tmp + gridx[x][y] + ""
tmp = tmp + "\n"
tmp = tmp[:-1]
tmp = tmp + "\\"
for i in range((width * 2) - 1):
tmp = tmp + " "
tmp = tmp + "/\n"
for i in range((width * 2) + 1):
tmp = tmp + ""
print(tmp)
if return_data:
return json.dumps({"action": "print", "data": tmp})
else:
await socket_broadcast(json.dumps({"action": "print", "data": tmp}))
start_server = websockets.serve(hello, "localhost", 8765)
loop = asyncio.get_event_loop()
loop.run_until_complete(reset())
def loop_in_thread():
loop.run_until_complete(start_server)
loop.run_forever()
thread = threading.Thread(loop_in_thread())
thread.start()