lobby add works need to do ready up next
This commit is contained in:
4
.idea/workspace.xml
generated
4
.idea/workspace.xml
generated
@@ -5,8 +5,12 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="67d0f8e4-ef35-4641-9e95-eb79cf01a045" name="Changes" comment="">
|
<list default="true" id="67d0f8e4-ef35-4641-9e95-eb79cf01a045" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/constants.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/client.py" beforeDir="false" afterPath="$PROJECT_DIR$/client.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/common.py" beforeDir="false" afterPath="$PROJECT_DIR$/common.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/common.py" beforeDir="false" afterPath="$PROJECT_DIR$/common.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/server.py" beforeDir="false" afterPath="$PROJECT_DIR$/server.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/vckonline.py" beforeDir="false" afterPath="$PROJECT_DIR$/vckonline.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
|||||||
141
client.py
141
client.py
@@ -1,49 +1,128 @@
|
|||||||
import wx
|
import wx
|
||||||
import socket
|
import socket
|
||||||
|
import threading
|
||||||
|
from constants import *
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class ClientVCKO(wx.App):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.frame = None
|
||||||
|
self.connection_status = None
|
||||||
|
self.in_lobby = None
|
||||||
|
self.player_id = None
|
||||||
|
|
||||||
|
def OnInit(self):
|
||||||
|
self.frame = MyFrame(self)
|
||||||
|
self.frame.Show()
|
||||||
|
self.connection_status = False
|
||||||
|
self.in_lobby = False
|
||||||
|
self.player_id = False
|
||||||
|
self.frame.set_connection_status()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def parse_response(self, response):
|
||||||
|
first_word = response.split()[0]
|
||||||
|
match first_word:
|
||||||
|
case "lobby":
|
||||||
|
full_command = response.split()
|
||||||
|
if full_command[1] == "joined" and len(full_command) == 3:
|
||||||
|
self.player_id = full_command[2]
|
||||||
|
self.in_lobby = True
|
||||||
|
print(self.player_id)
|
||||||
|
else:
|
||||||
|
print("Couldn't understand that response")
|
||||||
|
case _:
|
||||||
|
print(response)
|
||||||
|
|
||||||
|
|
||||||
class MyFrame(wx.Frame):
|
class MyFrame(wx.Frame):
|
||||||
def __init__(self):
|
def __init__(self, app):
|
||||||
super().__init__(parent=None, title='VCK Online')
|
super().__init__(parent=None, title='VCK Online', size=Constants.default_window_size)
|
||||||
panel = wx.Panel(self)
|
self.app = app
|
||||||
my_sizer = wx.BoxSizer(wx.VERTICAL)
|
self.panel = wx.Panel(self)
|
||||||
self.text_ctrl = wx.TextCtrl(panel)
|
self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
my_sizer.Add(self.text_ctrl, 0, wx.ALL | wx.EXPAND, 5)
|
self.status_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
my_btn = wx.Button(panel, label='Press Me')
|
self.message_field = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER)
|
||||||
my_btn.Bind(wx.EVT_BUTTON, self.on_press)
|
self.connection_status_indicator = wx.StaticText(self.panel, label="Connection Status")
|
||||||
my_sizer.Add(my_btn, 0, wx.ALL | wx.CENTER, 5)
|
self.my_btn = wx.Button(self.panel, label="Send call")
|
||||||
panel.SetSizer(my_sizer)
|
self.my_btn.Bind(wx.EVT_BUTTON, self.on_press)
|
||||||
self.host = "lukesau.com"
|
self.message_field.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter)
|
||||||
self.port = 8328 # socket server port number
|
# Create a horizontal sizer to hold the connection_status StaticText
|
||||||
self.header_size = 1024
|
self.status_sizer.AddStretchSpacer()
|
||||||
self.format = "utf-8"
|
self.status_sizer.Add(wx.StaticText(self.panel), 0, wx.EXPAND | wx.RIGHT, 5)
|
||||||
self.disconnect_message = "!DISCONNECT"
|
self.status_sizer.Add(self.connection_status_indicator, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
|
||||||
|
self.status_sizer.Add(wx.StaticText(self.panel), 0, wx.EXPAND | wx.LEFT, 5)
|
||||||
|
# Add the text field, button, and status sizer to the vertical sizer
|
||||||
|
self.vertical_sizer.Add(self.message_field, 0, wx.ALL | wx.EXPAND, 5)
|
||||||
|
self.vertical_sizer.Add(self.my_btn, 0, wx.ALL | wx.CENTER, 5)
|
||||||
|
self.vertical_sizer.AddStretchSpacer()
|
||||||
|
self.vertical_sizer.Add(self.status_sizer, 0, wx.ALIGN_LEFT | wx.BOTTOM, 5)
|
||||||
|
self.panel.SetSizer(self.vertical_sizer)
|
||||||
|
self.SetMinSize(Constants.minimum_window_size)
|
||||||
self.Show()
|
self.Show()
|
||||||
|
# Create a timer to call the connection_check method every 2 seconds
|
||||||
|
self.timer = wx.Timer(self)
|
||||||
|
self.Bind(wx.EVT_TIMER, self.set_connection_status, self.timer)
|
||||||
|
self.timer.Start(5000)
|
||||||
|
|
||||||
|
def set_connection_status(self, event=None):
|
||||||
|
if connection_check():
|
||||||
|
self.connection_status_indicator.SetLabel("Connected")
|
||||||
|
self.connection_status_indicator.SetForegroundColour(Constants.green)
|
||||||
|
else:
|
||||||
|
self.connection_status_indicator.SetLabel("Not Connected")
|
||||||
|
self.connection_status_indicator.SetForegroundColour(Constants.red)
|
||||||
|
|
||||||
def on_press(self, event):
|
def on_press(self, event):
|
||||||
message = self.text_ctrl.GetValue()
|
message = self.message_field.GetValue()
|
||||||
if not message:
|
if not message:
|
||||||
print("You didn't enter anything!")
|
print("You didn't enter anything!")
|
||||||
else:
|
else:
|
||||||
client_socket = socket.socket()
|
self.api_call(message)
|
||||||
client_socket.connect((self.host, self.port))
|
|
||||||
self.send(message, client_socket)
|
|
||||||
self.text_ctrl.SetValue("")
|
|
||||||
self.send(self.disconnect_message, client_socket)
|
|
||||||
|
|
||||||
def send(self, msg, input_socket):
|
def on_text_enter(self, event):
|
||||||
message = msg.encode(self.format)
|
message = self.message_field.GetValue()
|
||||||
|
if not message:
|
||||||
|
print("You didn't enter anything!")
|
||||||
|
else:
|
||||||
|
self.api_call(message)
|
||||||
|
|
||||||
|
def api_call(self, message):
|
||||||
|
if connection_check():
|
||||||
|
self.app.parse_response(send(message))
|
||||||
|
self.message_field.SetValue("")
|
||||||
|
|
||||||
|
|
||||||
|
def connection_check():
|
||||||
|
try:
|
||||||
|
response = send("connection_check")
|
||||||
|
if response == "received":
|
||||||
|
return True
|
||||||
|
except ConnectionRefusedError:
|
||||||
|
return False
|
||||||
|
except BrokenPipeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _send(msg, input_socket):
|
||||||
|
message = msg.encode(Constants.text_format)
|
||||||
msg_length = len(message)
|
msg_length = len(message)
|
||||||
print(msg_length)
|
send_length = str(msg_length).encode(Constants.text_format)
|
||||||
send_length = str(msg_length).encode(self.format)
|
send_length += b' ' * (Constants.header_size - len(send_length))
|
||||||
send_length += b' ' * (self.header_size - len(send_length))
|
|
||||||
input_socket.send(send_length)
|
input_socket.send(send_length)
|
||||||
input_socket.send(message)
|
input_socket.send(message)
|
||||||
print("done sending")
|
return input_socket.recv(2048).decode(Constants.text_format)
|
||||||
print(input_socket.recv(2048).decode(self.format))
|
|
||||||
|
|
||||||
|
def send(message):
|
||||||
|
client_socket = socket.socket()
|
||||||
|
client_socket.connect((Constants.host, Constants.port))
|
||||||
|
response = _send(message, client_socket)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = wx.App()
|
the_app = ClientVCKO()
|
||||||
frame = MyFrame()
|
the_app.MainLoop()
|
||||||
app.MainLoop()
|
|
||||||
|
|||||||
286
common.py
286
common.py
@@ -1,6 +1,8 @@
|
|||||||
import mysql.connector
|
import mysql.connector
|
||||||
import random
|
import random
|
||||||
from typing import List
|
from typing import List
|
||||||
|
import shortuuid
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
class Card:
|
class Card:
|
||||||
@@ -17,8 +19,9 @@ class Card:
|
|||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self):
|
def __init__(self, name, player_id):
|
||||||
self.name = "Player"
|
self.player_id = player_id
|
||||||
|
self.name = name
|
||||||
self.owned_starters = []
|
self.owned_starters = []
|
||||||
self.owned_citizens = []
|
self.owned_citizens = []
|
||||||
self.owned_domains = []
|
self.owned_domains = []
|
||||||
@@ -173,8 +176,9 @@ class Duke(Card):
|
|||||||
self.expansion = expansion
|
self.expansion = expansion
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Game:
|
||||||
def __init__(self, player_count, preset="shuffled", number_of_dukes=2):
|
def __init__(self, player_count, preset="shuffled", number_of_dukes=2):
|
||||||
|
self.game_id = uuid.uuid4()
|
||||||
self.player_count = player_count
|
self.player_count = player_count
|
||||||
self.preset = preset
|
self.preset = preset
|
||||||
self.number_of_dukes = number_of_dukes
|
self.number_of_dukes = number_of_dukes
|
||||||
@@ -254,10 +258,144 @@ class Board:
|
|||||||
self.monster_stack.append(my_monster)
|
self.monster_stack.append(my_monster)
|
||||||
my_connect.close()
|
my_connect.close()
|
||||||
# end load game data
|
# end load game data
|
||||||
self.remove_extra_cards()
|
# remove extra cards
|
||||||
|
if self.player_count != 5:
|
||||||
|
extra_monsters = []
|
||||||
|
remaining_monsters = []
|
||||||
|
for monster in self.monster_stack:
|
||||||
|
if monster.is_extra == 1:
|
||||||
|
extra_monsters.append(monster)
|
||||||
|
else:
|
||||||
|
remaining_monsters.append(monster)
|
||||||
|
self.monster_stack = remaining_monsters
|
||||||
|
self.graveyard.extend(extra_monsters)
|
||||||
|
match self.preset:
|
||||||
|
case "base1":
|
||||||
|
base1_monsters = []
|
||||||
|
other_expansion_monsters = []
|
||||||
|
for monster in self.monster_stack:
|
||||||
|
if monster.expansion == "base1":
|
||||||
|
base1_monsters.append(monster)
|
||||||
|
else:
|
||||||
|
other_expansion_monsters.append(monster)
|
||||||
|
self.monster_stack = base1_monsters
|
||||||
|
self.graveyard.extend(other_expansion_monsters)
|
||||||
|
base1_citizens = []
|
||||||
|
other_expansion_citizens = []
|
||||||
|
for citizen in self.citizen_stack:
|
||||||
|
if citizen.expansion == "base1":
|
||||||
|
base1_citizens.append(citizen)
|
||||||
|
else:
|
||||||
|
other_expansion_citizens.append(citizen)
|
||||||
|
self.citizen_stack = base1_citizens
|
||||||
|
self.graveyard.extend(other_expansion_citizens)
|
||||||
|
case "base2":
|
||||||
|
base1_monsters = []
|
||||||
|
base2_monsters = []
|
||||||
|
other_expansion_monsters = []
|
||||||
|
for monster in self.monster_stack:
|
||||||
|
if monster.expansion == "base1":
|
||||||
|
base1_monsters.append(monster)
|
||||||
|
elif monster.expansion == "base2":
|
||||||
|
base2_monsters.append(monster)
|
||||||
|
else:
|
||||||
|
other_expansion_monsters.append(monster)
|
||||||
|
# add 2 random monster areas from base1 to fill out base2 monsters
|
||||||
|
grouped_monsters = {}
|
||||||
|
for base1_monster in base1_monsters:
|
||||||
|
area = base1_monster.area
|
||||||
|
if area in grouped_monsters:
|
||||||
|
grouped_monsters[area].append(base1_monster)
|
||||||
|
else:
|
||||||
|
grouped_monsters[area] = [base1_monster]
|
||||||
|
areas = list(grouped_monsters.keys())
|
||||||
|
chosen_areas = random.sample(areas, 2)
|
||||||
|
not_chosen_monsters = [monster for area, monsters in grouped_monsters.items() if
|
||||||
|
area not in chosen_areas for monster in monsters]
|
||||||
|
self.graveyard.extend(not_chosen_monsters)
|
||||||
|
for i, area in enumerate(chosen_areas):
|
||||||
|
monsters = grouped_monsters[area]
|
||||||
|
base2_monsters.extend(monsters)
|
||||||
|
self.monster_stack = base2_monsters
|
||||||
|
self.graveyard.extend(other_expansion_monsters)
|
||||||
|
base2_citizens = []
|
||||||
|
other_expansion_citizens = []
|
||||||
|
for citizen in self.citizen_stack:
|
||||||
|
if citizen.expansion == "base2":
|
||||||
|
base2_citizens.append(citizen)
|
||||||
|
else:
|
||||||
|
other_expansion_citizens.append(citizen)
|
||||||
|
# add peasant and knight from base1
|
||||||
|
for citizen in other_expansion_citizens:
|
||||||
|
if citizen.name == "Peasant" and citizen.expansion == "base1":
|
||||||
|
base2_citizens.append(citizen)
|
||||||
|
elif citizen.name == "Knight" and citizen.expansion == "base1":
|
||||||
|
base2_citizens.append(citizen)
|
||||||
|
self.citizen_stack = base2_citizens
|
||||||
|
# put the rest of the cards in the graveyard
|
||||||
|
grouped_citizens = {}
|
||||||
|
for citizen in other_expansion_citizens:
|
||||||
|
expansion = citizen.expansion
|
||||||
|
if expansion in grouped_citizens:
|
||||||
|
grouped_citizens[expansion].append(citizen)
|
||||||
|
else:
|
||||||
|
grouped_citizens[expansion] = [citizen]
|
||||||
|
if "base1" in grouped_citizens:
|
||||||
|
base1_citizens = grouped_citizens["base1"]
|
||||||
|
base1_citizens = [citizen for citizen in base1_citizens if
|
||||||
|
citizen.name not in ("Peasant", "Knight")]
|
||||||
|
grouped_citizens["base1"] = base1_citizens
|
||||||
|
other_expansion_citizens = []
|
||||||
|
for expansion in grouped_citizens.values():
|
||||||
|
other_expansion_citizens.extend(expansion)
|
||||||
|
self.graveyard.extend(other_expansion_citizens)
|
||||||
|
case "shadowvale":
|
||||||
|
shadowvale_monsters = []
|
||||||
|
other_expansion_monsters = []
|
||||||
|
for monster in self.monster_stack:
|
||||||
|
if monster.expansion == "shadowvale":
|
||||||
|
shadowvale_monsters.append(monster)
|
||||||
|
else:
|
||||||
|
other_expansion_monsters.append(monster)
|
||||||
|
self.monster_stack = shadowvale_monsters
|
||||||
|
self.graveyard.extend(other_expansion_monsters)
|
||||||
|
shadowvale_citizens = []
|
||||||
|
other_expansion_citizens = []
|
||||||
|
for citizen in self.citizen_stack:
|
||||||
|
if citizen.expansion == "shadowvale":
|
||||||
|
shadowvale_citizens.append(citizen)
|
||||||
|
else:
|
||||||
|
other_expansion_citizens.append(citizen)
|
||||||
|
self.citizen_stack = shadowvale_citizens
|
||||||
|
self.graveyard.extend(other_expansion_citizens)
|
||||||
|
case "flamesandfrost":
|
||||||
|
flamesandfrost_monsters = []
|
||||||
|
other_expansion_monsters = []
|
||||||
|
for monster in self.monster_stack:
|
||||||
|
if monster.expansion == "flamesandfrost":
|
||||||
|
flamesandfrost_monsters.append(monster)
|
||||||
|
else:
|
||||||
|
other_expansion_monsters.append(monster)
|
||||||
|
self.monster_stack = flamesandfrost_monsters
|
||||||
|
self.graveyard.extend(other_expansion_monsters)
|
||||||
|
flamesandfrost_citizens = []
|
||||||
|
other_expansion_citizens = []
|
||||||
|
for citizen in self.citizen_stack:
|
||||||
|
if citizen.expansion == "flamesandfrost":
|
||||||
|
flamesandfrost_citizens.append(citizen)
|
||||||
|
else:
|
||||||
|
other_expansion_citizens.append(citizen)
|
||||||
|
self.citizen_stack = flamesandfrost_citizens
|
||||||
|
self.graveyard.extend(other_expansion_citizens)
|
||||||
|
case _:
|
||||||
|
if self.player_count != 5:
|
||||||
|
for stack in self.monster_grid:
|
||||||
|
# Remove monsters with isExtra = True from each stack
|
||||||
|
stack[:] = [monster for monster in stack if not monster.is_extra]
|
||||||
|
# end remove extra cards
|
||||||
# create players and determine order
|
# create players and determine order
|
||||||
for x in range(0, self.player_count):
|
for x in range(0, self.player_count):
|
||||||
my_player = Player()
|
my_player = Player(shortuuid.uuid())
|
||||||
my_player.name = f"Player {(x + 1)}"
|
my_player.name = f"Player {(x + 1)}"
|
||||||
self.player_list.append(my_player)
|
self.player_list.append(my_player)
|
||||||
random.shuffle(self.player_list)
|
random.shuffle(self.player_list)
|
||||||
@@ -317,140 +455,9 @@ class Board:
|
|||||||
else: # other domains are not visible or accessible
|
else: # other domains are not visible or accessible
|
||||||
domain = self.domain_stack.pop()
|
domain = self.domain_stack.pop()
|
||||||
stack.append(domain)
|
stack.append(domain)
|
||||||
self.get_board_state()
|
self.get_game_state()
|
||||||
|
|
||||||
def remove_extra_cards(self):
|
def get_game_state(self):
|
||||||
if self.player_count != 5:
|
|
||||||
extra_monsters = []
|
|
||||||
remaining_monsters = []
|
|
||||||
for monster in self.monster_stack:
|
|
||||||
if monster.is_extra == 1:
|
|
||||||
extra_monsters.append(monster)
|
|
||||||
else:
|
|
||||||
remaining_monsters.append(monster)
|
|
||||||
self.monster_stack = remaining_monsters
|
|
||||||
self.graveyard.extend(extra_monsters)
|
|
||||||
match self.preset:
|
|
||||||
case "base1":
|
|
||||||
base1_monsters = []
|
|
||||||
other_expansion_monsters = []
|
|
||||||
for monster in self.monster_stack:
|
|
||||||
if monster.expansion == "base1":
|
|
||||||
base1_monsters.append(monster)
|
|
||||||
else:
|
|
||||||
other_expansion_monsters.append(monster)
|
|
||||||
self.monster_stack = base1_monsters
|
|
||||||
self.graveyard.extend(other_expansion_monsters)
|
|
||||||
base1_citizens = []
|
|
||||||
other_expansion_citizens = []
|
|
||||||
for citizen in self.citizen_stack:
|
|
||||||
if citizen.expansion == "base1":
|
|
||||||
base1_citizens.append(citizen)
|
|
||||||
else:
|
|
||||||
other_expansion_citizens.append(citizen)
|
|
||||||
self.citizen_stack = base1_citizens
|
|
||||||
self.graveyard.extend(other_expansion_citizens)
|
|
||||||
case "base2":
|
|
||||||
base1_monsters = []
|
|
||||||
base2_monsters = []
|
|
||||||
other_expansion_monsters = []
|
|
||||||
for monster in self.monster_stack:
|
|
||||||
if monster.expansion == "base1":
|
|
||||||
base1_monsters.append(monster)
|
|
||||||
elif monster.expansion == "base2":
|
|
||||||
base2_monsters.append(monster)
|
|
||||||
else:
|
|
||||||
other_expansion_monsters.append(monster)
|
|
||||||
# add 2 random monster areas from base1 to fill out base2 monsters
|
|
||||||
grouped_monsters = {}
|
|
||||||
for base1_monster in base1_monsters:
|
|
||||||
area = base1_monster.area
|
|
||||||
if area in grouped_monsters:
|
|
||||||
grouped_monsters[area].append(base1_monster)
|
|
||||||
else:
|
|
||||||
grouped_monsters[area] = [base1_monster]
|
|
||||||
areas = list(grouped_monsters.keys())
|
|
||||||
chosen_areas = random.sample(areas, 2)
|
|
||||||
not_chosen_monsters = [monster for area, monsters in grouped_monsters.items() if area not in chosen_areas for monster in monsters]
|
|
||||||
self.graveyard.extend(not_chosen_monsters)
|
|
||||||
for i, area in enumerate(chosen_areas):
|
|
||||||
monsters = grouped_monsters[area]
|
|
||||||
base2_monsters.extend(monsters)
|
|
||||||
self.monster_stack = base2_monsters
|
|
||||||
self.graveyard.extend(other_expansion_monsters)
|
|
||||||
base2_citizens = []
|
|
||||||
other_expansion_citizens = []
|
|
||||||
for citizen in self.citizen_stack:
|
|
||||||
if citizen.expansion == "base2":
|
|
||||||
base2_citizens.append(citizen)
|
|
||||||
else:
|
|
||||||
other_expansion_citizens.append(citizen)
|
|
||||||
for citizen in other_expansion_citizens:
|
|
||||||
if citizen.name == "Peasant" and citizen.expansion == "base1":
|
|
||||||
base2_citizens.append(citizen)
|
|
||||||
elif citizen.name == "Knight" and citizen.expansion == "base1":
|
|
||||||
base2_citizens.append(citizen)
|
|
||||||
self.citizen_stack = base2_citizens
|
|
||||||
grouped_citizens = {}
|
|
||||||
for citizen in other_expansion_citizens:
|
|
||||||
expansion = citizen.expansion
|
|
||||||
if expansion in grouped_citizens:
|
|
||||||
grouped_citizens[expansion].append(citizen)
|
|
||||||
else:
|
|
||||||
grouped_citizens[expansion] = [citizen]
|
|
||||||
if "base1" in grouped_citizens:
|
|
||||||
base1_citizens = grouped_citizens["base1"]
|
|
||||||
base1_citizens = [citizen for citizen in base1_citizens if citizen.name not in ("Peasant", "Knight")]
|
|
||||||
grouped_citizens["base1"] = base1_citizens
|
|
||||||
other_expansion_citizens = []
|
|
||||||
for expansion in grouped_citizens.values():
|
|
||||||
other_expansion_citizens.extend(expansion)
|
|
||||||
self.graveyard.extend(other_expansion_citizens)
|
|
||||||
case "shadowvale":
|
|
||||||
shadowvale_monsters = []
|
|
||||||
other_expansion_monsters = []
|
|
||||||
for monster in self.monster_stack:
|
|
||||||
if monster.expansion == "shadowvale":
|
|
||||||
shadowvale_monsters.append(monster)
|
|
||||||
else:
|
|
||||||
other_expansion_monsters.append(monster)
|
|
||||||
self.monster_stack = shadowvale_monsters
|
|
||||||
self.graveyard.extend(other_expansion_monsters)
|
|
||||||
shadowvale_citizens = []
|
|
||||||
other_expansion_citizens = []
|
|
||||||
for citizen in self.citizen_stack:
|
|
||||||
if citizen.expansion == "shadowvale":
|
|
||||||
shadowvale_citizens.append(citizen)
|
|
||||||
else:
|
|
||||||
other_expansion_citizens.append(citizen)
|
|
||||||
self.citizen_stack = shadowvale_citizens
|
|
||||||
self.graveyard.extend(other_expansion_citizens)
|
|
||||||
case "flamesandfrost":
|
|
||||||
flamesandfrost_monsters = []
|
|
||||||
other_expansion_monsters = []
|
|
||||||
for monster in self.monster_stack:
|
|
||||||
if monster.expansion == "flamesandfrost":
|
|
||||||
flamesandfrost_monsters.append(monster)
|
|
||||||
else:
|
|
||||||
other_expansion_monsters.append(monster)
|
|
||||||
self.monster_stack = flamesandfrost_monsters
|
|
||||||
self.graveyard.extend(other_expansion_monsters)
|
|
||||||
flamesandfrost_citizens = []
|
|
||||||
other_expansion_citizens = []
|
|
||||||
for citizen in self.citizen_stack:
|
|
||||||
if citizen.expansion == "flamesandfrost":
|
|
||||||
flamesandfrost_citizens.append(citizen)
|
|
||||||
else:
|
|
||||||
other_expansion_citizens.append(citizen)
|
|
||||||
self.citizen_stack = flamesandfrost_citizens
|
|
||||||
self.graveyard.extend(other_expansion_citizens)
|
|
||||||
case _:
|
|
||||||
if self.player_count != 5:
|
|
||||||
for stack in self.monster_grid:
|
|
||||||
# Remove monsters with isExtra = True from each stack
|
|
||||||
stack[:] = [monster for monster in stack if not monster.is_extra]
|
|
||||||
|
|
||||||
def get_board_state(self):
|
|
||||||
for i, monster_list in enumerate(self.monster_grid):
|
for i, monster_list in enumerate(self.monster_grid):
|
||||||
print(
|
print(
|
||||||
f"Monster Stack {i + 1}: {[f'{monster.name} ({monster.monster_id})' + ('E' if monster.is_extra else '') + ('V' if monster.is_visible else '') + ('A' if monster.is_accessible else '') for monster in monster_list]}")
|
f"Monster Stack {i + 1}: {[f'{monster.name} ({monster.monster_id})' + ('E' if monster.is_extra else '') + ('V' if monster.is_visible else '') + ('A' if monster.is_accessible else '') for monster in monster_list]}")
|
||||||
@@ -460,6 +467,9 @@ class Board:
|
|||||||
for i, domain_list in enumerate(self.domain_grid):
|
for i, domain_list in enumerate(self.domain_grid):
|
||||||
print(
|
print(
|
||||||
f"Domain Stack {i + 1}: {[f'{domain.name} ({domain.domain_id})' + ('V' if domain.is_visible else '') + ('A' if domain.is_accessible else '') for domain in domain_list]}")
|
f"Domain Stack {i + 1}: {[f'{domain.name} ({domain.domain_id})' + ('V' if domain.is_visible else '') + ('A' if domain.is_accessible else '') for domain in domain_list]}")
|
||||||
|
for i, player in enumerate(self.player_list):
|
||||||
|
print(
|
||||||
|
f"Player {i + 1}: {[f'{player.name} ({player.player_id})' + (' *' if player.is_first else '') + f' G{player.gold_score} S{player.strength_score} M{player.magic_score}']}")
|
||||||
print(f"monster stack size {len(self.monster_stack)}")
|
print(f"monster stack size {len(self.monster_stack)}")
|
||||||
print(f"citizen stack size {len(self.citizen_stack)}")
|
print(f"citizen stack size {len(self.citizen_stack)}")
|
||||||
print(f"domain stack size {len(self.domain_stack)}")
|
print(f"domain stack size {len(self.domain_stack)}")
|
||||||
|
|||||||
9
constants.py
Normal file
9
constants.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
class Constants:
|
||||||
|
green = (106, 171, 115)
|
||||||
|
red = (219, 92, 92)
|
||||||
|
host = "127.0.1.1"
|
||||||
|
port = 8328
|
||||||
|
header_size = 1024
|
||||||
|
text_format = "utf-8"
|
||||||
|
minimum_window_size = (300, 150)
|
||||||
|
default_window_size = (300, 150)
|
||||||
53
server.py
53
server.py
@@ -2,31 +2,59 @@ import socket
|
|||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from common import *
|
from common import *
|
||||||
|
from constants import *
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
class ServerVCKO:
|
class ServerVCKO:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.host = socket.gethostname()
|
self.host = socket.gethostname()
|
||||||
self.port = 8328
|
|
||||||
self.header_size = 1024
|
|
||||||
self.format = "utf-8"
|
|
||||||
self.disconnect_message = "!DISCONNECT"
|
|
||||||
self.server_socket = socket.socket()
|
self.server_socket = socket.socket()
|
||||||
self.server_socket.bind((self.host, self.port))
|
self.server_socket.bind((self.host, Constants.port))
|
||||||
self.game_list = []
|
self.game_list = []
|
||||||
|
self.lobby = []
|
||||||
|
|
||||||
def handle_client(self, conn, addr):
|
def handle_client(self, conn, addr):
|
||||||
print(f"Connection from: {addr}")
|
print(f"Connection from: {addr}")
|
||||||
connected = True
|
connected = True
|
||||||
while connected:
|
while connected:
|
||||||
msg_length = conn.recv(self.header_size).decode(self.format)
|
msg_length = conn.recv(Constants.header_size).decode(Constants.text_format)
|
||||||
if msg_length:
|
if msg_length:
|
||||||
msg_length = int(msg_length)
|
msg_length = int(msg_length)
|
||||||
msg = conn.recv(msg_length).decode(self.format)
|
msg = conn.recv(msg_length).decode(Constants.text_format)
|
||||||
if msg == self.disconnect_message:
|
first_word = msg.split()[0]
|
||||||
|
match first_word:
|
||||||
|
case "connection_check":
|
||||||
connected = False
|
connected = False
|
||||||
|
conn.send("received".encode(Constants.text_format))
|
||||||
|
case "lobby":
|
||||||
|
connected = False
|
||||||
|
full_command = msg.split()
|
||||||
|
if full_command[1] == "join" and len(full_command) > 2:
|
||||||
|
joining_player_name = ' '.join(full_command[2:])
|
||||||
|
joining_player_id = shortuuid.uuid()
|
||||||
|
joining_player = LobbyMember(joining_player_name, joining_player_id)
|
||||||
|
self.lobby.append(joining_player)
|
||||||
|
message = f"lobby joined {joining_player_id}"
|
||||||
|
conn.send(joining_player_id.encode(Constants.text_format))
|
||||||
|
elif full_command[1] == "get_status":
|
||||||
|
lobby_data = []
|
||||||
|
for lobby_member in self.lobby:
|
||||||
|
player_dict = {
|
||||||
|
"name": lobby_member.name,
|
||||||
|
"player_id": lobby_member.player_id,
|
||||||
|
"is_ready": lobby_member.is_ready
|
||||||
|
}
|
||||||
|
lobby_data.append(player_dict)
|
||||||
|
json_data = json.dumps(lobby_data)
|
||||||
|
print(json_data)
|
||||||
|
conn.send(json_data.encode(Constants.text_format))
|
||||||
|
else:
|
||||||
|
conn.send("invalid message".encode(Constants.text_format))
|
||||||
|
case _:
|
||||||
|
connected = False
|
||||||
|
conn.send("invalid message".encode(Constants.text_format))
|
||||||
print(f"[{addr}] {msg}")
|
print(f"[{addr}] {msg}")
|
||||||
conn.send("msg received".encode(self.format))
|
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
@@ -39,6 +67,13 @@ class ServerVCKO:
|
|||||||
print(f"Active threads: {threading.active_count() - 1}")
|
print(f"Active threads: {threading.active_count() - 1}")
|
||||||
|
|
||||||
|
|
||||||
|
class LobbyMember:
|
||||||
|
def __init__(self, player_name, player_id):
|
||||||
|
self.name = player_name
|
||||||
|
self.player_id = player_id
|
||||||
|
self.is_ready = False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print("server starting")
|
print("server starting")
|
||||||
server = ServerVCKO()
|
server = ServerVCKO()
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ from common import *
|
|||||||
|
|
||||||
print("Welcome to Valeria Card Kingdoms: Online")
|
print("Welcome to Valeria Card Kingdoms: Online")
|
||||||
player_count = 4
|
player_count = 4
|
||||||
citizen_set = "shadowvale" # base1, base2, shadowvale, flamesandfrost, crimsonseas, shuffled
|
citizen_set = "base2" # base1, base2, shadowvale, flamesandfrost, crimsonseas, shuffled
|
||||||
game_board = Board(player_count, citizen_set)
|
game_board = Game(player_count, citizen_set)
|
||||||
game_board.play_turn()
|
game_board.play_turn()
|
||||||
|
|||||||
Reference in New Issue
Block a user