Init
This commit is contained in:
parent
5915270af5
commit
2ce2ce50f2
116
.gitignore
vendored
Normal file
116
.gitignore
vendored
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# IPython
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Pyre type checker
|
||||||
|
.pyre/
|
||||||
|
|
||||||
|
.idea/
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 BRNSystems
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
2
README.md
Normal file
2
README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Bendzove_Piskvorky
|
||||||
|
A small network game
|
83
local.py
Normal file
83
local.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
width = 9
|
||||||
|
height = 6
|
||||||
|
|
||||||
|
grid = []
|
||||||
|
|
||||||
|
for _ in range(width):
|
||||||
|
temp_grid = []
|
||||||
|
for _ in range(height):
|
||||||
|
temp_grid.append(" ")
|
||||||
|
grid.append(temp_grid)
|
||||||
|
|
||||||
|
player = 0
|
||||||
|
|
||||||
|
|
||||||
|
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] = " "
|
||||||
|
|
||||||
|
|
||||||
|
def add(gridx, col3):
|
||||||
|
try:
|
||||||
|
col = int(col3)
|
||||||
|
except ValueError:
|
||||||
|
return 2
|
||||||
|
if -1 < col < width:
|
||||||
|
global player
|
||||||
|
if gridx[col][0] == " ":
|
||||||
|
if player == 1:
|
||||||
|
gridx[col][0] = "O"
|
||||||
|
player = 0
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
gridx[col][0] = "X"
|
||||||
|
player = 1
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
return 2
|
||||||
|
|
||||||
|
|
||||||
|
def draw(gridx):
|
||||||
|
tempstorage = ""
|
||||||
|
for _ in range((width * 2) + 1):
|
||||||
|
tempstorage = tempstorage + "_"
|
||||||
|
tempstorage = tempstorage + "\n|"
|
||||||
|
for i in range(0, width):
|
||||||
|
tempstorage = tempstorage + f"{i}|"
|
||||||
|
tempstorage = tempstorage + "\n|"
|
||||||
|
for y in range(0, height):
|
||||||
|
for x in range(0, width):
|
||||||
|
tempstorage = tempstorage + gridx[x][y] + "|"
|
||||||
|
tempstorage = tempstorage + "\n|"
|
||||||
|
tempstorage = tempstorage[:-1]
|
||||||
|
for _ in range((width * 2) + 1):
|
||||||
|
tempstorage = tempstorage + "¯"
|
||||||
|
print(tempstorage)
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
draw(grid)
|
||||||
|
col2 = input(f"It is player{player} 's turn, input column number from 0 to {width - 1}:")
|
||||||
|
success = add(grid, col2)
|
||||||
|
while success != 1:
|
||||||
|
if success == 2:
|
||||||
|
col2 = input(f"Oops you have entered '{col2}' which is not a valid input. Please try again player{player}:")
|
||||||
|
elif success == 0:
|
||||||
|
col2 = input(f"Oops you have entered '{col2}' which is full. Please try again player{player}:")
|
||||||
|
success = add(grid, col2)
|
||||||
|
apply_gravity(grid)
|
||||||
|
draw(grid)
|
84
main.py
Normal file
84
main.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import aioconsole
|
||||||
|
import websockets
|
||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
|
||||||
|
IP = "localhost:8765"
|
||||||
|
|
||||||
|
player_id = 0
|
||||||
|
ws = websockets.connect("ws://" + IP)
|
||||||
|
connected = False
|
||||||
|
|
||||||
|
got_message = False
|
||||||
|
|
||||||
|
|
||||||
|
async def connect():
|
||||||
|
global ws
|
||||||
|
global connected
|
||||||
|
async with websockets.connect("ws://localhost:8765") as wsx:
|
||||||
|
ws = wsx
|
||||||
|
connected = True
|
||||||
|
while True:
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
|
||||||
|
|
||||||
|
async def recieve_data_to_server():
|
||||||
|
while not connected:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
global ws
|
||||||
|
global player_id
|
||||||
|
global got_message
|
||||||
|
while True:
|
||||||
|
async for message in ws:
|
||||||
|
try:
|
||||||
|
data = json.loads(message)
|
||||||
|
if data["action"] == "redraw":
|
||||||
|
print(data["data"])
|
||||||
|
got_message = True
|
||||||
|
elif data["action"] == "info":
|
||||||
|
print(data["data"])
|
||||||
|
got_message = True
|
||||||
|
elif data["action"] == "id":
|
||||||
|
player_id = data["id"]
|
||||||
|
if got_message:
|
||||||
|
print("Enter command:\n")
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
|
||||||
|
async def send_data_to_server():
|
||||||
|
while not connected:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
global ws
|
||||||
|
global player_id
|
||||||
|
while True:
|
||||||
|
cmd = await aioconsole.ainput("Enter command:\n")
|
||||||
|
if cmd == "reset":
|
||||||
|
await ws.send(json.dumps({"action": "reset"}))
|
||||||
|
elif cmd == "redraw":
|
||||||
|
await ws.send(json.dumps({"action": "redraw"}))
|
||||||
|
elif cmd.startswith("resize"):
|
||||||
|
cmd_args = cmd.split(" ")
|
||||||
|
if len(cmd_args) >= 3:
|
||||||
|
await ws.send(json.dumps({"action": "resize", "width": cmd_args[1], "height": cmd_args[2]}))
|
||||||
|
else:
|
||||||
|
print("Incorrect argument number.")
|
||||||
|
elif cmd.startswith("add"):
|
||||||
|
cmd_args = cmd.split(" ")
|
||||||
|
if len(cmd_args) >= 2:
|
||||||
|
await ws.send(json.dumps({"action": "add", "col": cmd_args[1], "id": player_id}))
|
||||||
|
elif cmd == "help":
|
||||||
|
await ws.send(json.dumps({"action": "help"}))
|
||||||
|
else:
|
||||||
|
print("Unknown command. Type 'help' to list all commands.")
|
||||||
|
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
|
async def run_stuff():
|
||||||
|
await asyncio.gather(connect(), recieve_data_to_server(), send_data_to_server())
|
||||||
|
|
||||||
|
|
||||||
|
asyncio.run(run_stuff())
|
190
server.py
Normal file
190
server.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
import asyncio
|
||||||
|
import json
|
||||||
|
import random
|
||||||
|
import websockets
|
||||||
|
import threading
|
||||||
|
|
||||||
|
width = 9
|
||||||
|
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
|
||||||
|
i = 0
|
||||||
|
connected.add(ws)
|
||||||
|
this_id = random.randint(0, 100000)
|
||||||
|
players.append({"ws": ws, "id": this_id})
|
||||||
|
if len(players) >= 3:
|
||||||
|
await socket_broadcast(json.dumps({"action": "info", "data": f"Warning {len(players)} players are connected"}))
|
||||||
|
await ws.send(json.dumps({"action": "id", "id": this_id}))
|
||||||
|
try:
|
||||||
|
while i == 0:
|
||||||
|
try:
|
||||||
|
x = await ws.recv()
|
||||||
|
try:
|
||||||
|
temp = json.loads(x)
|
||||||
|
print(str(temp) + " data")
|
||||||
|
if temp["action"] == "reset":
|
||||||
|
await reset()
|
||||||
|
await draw(grid)
|
||||||
|
await socket_broadcast(
|
||||||
|
json.dumps({"action": "info", "data": f"It is player{player_on_turn} 's turn."}))
|
||||||
|
await players[player_on_turn]['ws'].send(json.dumps(
|
||||||
|
{"action": "info", "data": f"It is your turn, input column number from 0 to {width - 1}:"}))
|
||||||
|
elif temp["action"] == "redraw":
|
||||||
|
await ws.send(await draw(grid, True))
|
||||||
|
elif temp["action"] == "resize":
|
||||||
|
try:
|
||||||
|
width = int(temp["width"])
|
||||||
|
height = int(temp["height"])
|
||||||
|
await reset()
|
||||||
|
await ws.send(await draw(grid, True))
|
||||||
|
await socket_broadcast(
|
||||||
|
json.dumps({"action": "info", "data": f"It is player{player_on_turn} 's turn."}))
|
||||||
|
await players[player_on_turn]['ws'].send(json.dumps({"action": "info",
|
||||||
|
"data": f"It is your turn, type 'add (number of column from 0 to {width - 1}' :"}))
|
||||||
|
except ValueError:
|
||||||
|
await ws.send(json.dumps({"action": "info", "data": "Invalid arguments to resize."}))
|
||||||
|
elif temp["action"] == "add":
|
||||||
|
plx = 0
|
||||||
|
for player in players:
|
||||||
|
if temp["id"] == player["id"]:
|
||||||
|
if plx == player_on_turn:
|
||||||
|
res = await add(grid, temp["col"])
|
||||||
|
if res == 1:
|
||||||
|
await apply_gravity(grid)
|
||||||
|
await socket_broadcast(await draw(grid, True))
|
||||||
|
await socket_broadcast(json.dumps(
|
||||||
|
{"action": "info", "data": f"It is player{player_on_turn} 's turn."}))
|
||||||
|
await players[player_on_turn]['ws'].send(json.dumps({"action": "info",
|
||||||
|
"data": f"It is your turn, input column number from 0 to {width - 1}:"}))
|
||||||
|
elif res == 2:
|
||||||
|
await players[player_on_turn]['ws'].send(json.dumps({"action": "info",
|
||||||
|
"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": "info",
|
||||||
|
"data": f"Oops you have entered '{temp['col']}' which is full. Please try again player{player_on_turn}:"}))
|
||||||
|
plx = plx + 1
|
||||||
|
elif temp["action"] == "help":
|
||||||
|
await ws.send(json.dumps({"action": "info",
|
||||||
|
"data": f"\n'reset' - Resets the game, also you must start the game with this\n'redraw' - Sends you the current state of th 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'help' - Prints this help message"}))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
connected.remove(ws)
|
||||||
|
i = 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):
|
||||||
|
temporary_storage = ""
|
||||||
|
for _ in range((width * 2) + 1):
|
||||||
|
temporary_storage = temporary_storage + "_"
|
||||||
|
temporary_storage = temporary_storage + "\n|"
|
||||||
|
for i in range(0, width):
|
||||||
|
temporary_storage = temporary_storage + f"{i}|"
|
||||||
|
temporary_storage = temporary_storage + "\n|"
|
||||||
|
for y in range(0, height):
|
||||||
|
for x in range(0, width):
|
||||||
|
temporary_storage = temporary_storage + gridx[x][y] + "|"
|
||||||
|
temporary_storage = temporary_storage + "\n|"
|
||||||
|
temporary_storage = temporary_storage[:-1]
|
||||||
|
for _ in range((width * 2) + 1):
|
||||||
|
temporary_storage = temporary_storage + "¯"
|
||||||
|
print(temporary_storage)
|
||||||
|
if return_data:
|
||||||
|
return json.dumps({"action": "redraw", "data": temporary_storage})
|
||||||
|
else:
|
||||||
|
await socket_broadcast(json.dumps({"action": "redraw", "data": temporary_storage}))
|
||||||
|
|
||||||
|
|
||||||
|
start_server = websockets.serve(hello, "localhost", 8765)
|
||||||
|
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
|
||||||
|
def loop_in_thread():
|
||||||
|
loop.run_until_complete(start_server)
|
||||||
|
loop.run_forever()
|
||||||
|
|
||||||
|
|
||||||
|
thread = threading.Thread(loop_in_thread())
|
||||||
|
thread.start()
|
Loading…
Reference in New Issue
Block a user