lobby ready up works
This commit is contained in:
4
.idea/vckonline.iml
generated
4
.idea/vckonline.iml
generated
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module version="4">
|
<module version="4">
|
||||||
<component name="PyDocumentationSettings">
|
<component name="PyDocumentationSettings">
|
||||||
<option name="format" value="PLAIN" />
|
<option name="format" value="GOOGLE" />
|
||||||
<option name="myDocStringFormat" value="Plain" />
|
<option name="myDocStringFormat" value="Google" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
2
.idea/workspace.xml
generated
2
.idea/workspace.xml
generated
@@ -7,7 +7,9 @@
|
|||||||
<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 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$/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$/server.py" beforeDir="false" afterPath="$PROJECT_DIR$/server.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" />
|
||||||
|
|||||||
167
client.py
167
client.py
@@ -7,36 +7,41 @@ import json
|
|||||||
|
|
||||||
class ClientVCKO(wx.App):
|
class ClientVCKO(wx.App):
|
||||||
def OnInit(self):
|
def OnInit(self):
|
||||||
self.frame = MyFrame(self)
|
self.debug_frame = DebugFrame(self)
|
||||||
self.frame.Show()
|
self.debug_frame.Show()
|
||||||
|
self.start_frame = StartFrame(self)
|
||||||
|
self.debug_frame.Show()
|
||||||
self.connection_status = False
|
self.connection_status = False
|
||||||
self.in_lobby = False
|
self.in_lobby = False
|
||||||
self.player_id = False
|
self.player_id = ""
|
||||||
self.frame.set_connection_status()
|
self.debug_frame.set_connection_status()
|
||||||
|
self.lobby = []
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def parse_response(self, response):
|
def parse_response(self, response):
|
||||||
print(f"{response}")
|
print(f"{response}")
|
||||||
first_word = response.split()[0]
|
first_word = response.split()[0]
|
||||||
|
full_command = response.split()
|
||||||
match first_word:
|
match first_word:
|
||||||
case "lobby":
|
case "lobby":
|
||||||
full_command = response.split()
|
full_command = response.split()
|
||||||
if full_command[1] == "joined" and len(full_command) == 3:
|
if full_command[1] == "joined" and len(full_command) == 3:
|
||||||
self.player_id = full_command[2]
|
self.player_id = full_command[2]
|
||||||
self.in_lobby = True
|
self.in_lobby = True
|
||||||
print(self.player_id)
|
self.start_frame.show_list_view(None)
|
||||||
print(self.frame)
|
elif full_command[1] == "state":
|
||||||
self.frame.show_list_view(None)
|
json_response = ' '.join(full_command[2:])
|
||||||
print("did it work")
|
print(json_response)
|
||||||
|
self.lobby = json.loads(json_response)
|
||||||
else:
|
else:
|
||||||
print("Couldn't understand that response")
|
print("Couldn't understand that response")
|
||||||
case _:
|
case _:
|
||||||
print(response)
|
print(full_command[1])
|
||||||
|
|
||||||
|
|
||||||
class MyFrame(wx.Frame):
|
class DebugFrame(wx.Frame):
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
super().__init__(parent=None, title='VCK Online', size=Constants.default_window_size)
|
super().__init__(parent=None, title='VCKO Debug Console', size=Constants.default_window_size)
|
||||||
self.app = app
|
self.app = app
|
||||||
self.panel = wx.Panel(self)
|
self.panel = wx.Panel(self)
|
||||||
self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
|
self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
@@ -64,27 +69,6 @@ class MyFrame(wx.Frame):
|
|||||||
self.Bind(wx.EVT_TIMER, self.set_connection_status, self.timer)
|
self.Bind(wx.EVT_TIMER, self.set_connection_status, self.timer)
|
||||||
self.timer.Start(5000)
|
self.timer.Start(5000)
|
||||||
|
|
||||||
def show_list_view(self, event):
|
|
||||||
print("show list view")
|
|
||||||
# create a list view with a ready up button
|
|
||||||
list_ctrl = wx.ListCtrl(self.panel, style=wx.LC_REPORT)
|
|
||||||
list_ctrl.InsertColumn(0, "Player ID")
|
|
||||||
list_ctrl.InsertColumn(1, "Ready Status")
|
|
||||||
list_ctrl.InsertItem(0, self.app.player_id)
|
|
||||||
list_ctrl.SetItem(0, 1, "Not Ready")
|
|
||||||
|
|
||||||
ready_button = wx.Button(self.panel, label="Ready Up")
|
|
||||||
ready_button.Bind(wx.EVT_BUTTON, self.on_ready_up)
|
|
||||||
|
|
||||||
# Add the list view and button to the vertical sizer
|
|
||||||
self.vertical_sizer.Insert(0, list_ctrl, 0, wx.ALL | wx.EXPAND, 5)
|
|
||||||
self.vertical_sizer.Add(ready_button, 0, wx.ALL | wx.CENTER, 5)
|
|
||||||
self.panel.Layout()
|
|
||||||
|
|
||||||
def on_ready_up(self, event):
|
|
||||||
# implement ready up functionality here
|
|
||||||
print("Ready Up button pressed!")
|
|
||||||
|
|
||||||
def set_connection_status(self, event=None):
|
def set_connection_status(self, event=None):
|
||||||
if connection_check():
|
if connection_check():
|
||||||
self.connection_status_indicator.SetLabel("Connected")
|
self.connection_status_indicator.SetLabel("Connected")
|
||||||
@@ -101,11 +85,7 @@ class MyFrame(wx.Frame):
|
|||||||
self.api_call(message)
|
self.api_call(message)
|
||||||
|
|
||||||
def on_text_enter(self, event):
|
def on_text_enter(self, event):
|
||||||
message = self.message_field.GetValue()
|
self.on_press(event)
|
||||||
if not message:
|
|
||||||
print("You didn't enter anything!")
|
|
||||||
else:
|
|
||||||
self.api_call(message)
|
|
||||||
|
|
||||||
def api_call(self, message):
|
def api_call(self, message):
|
||||||
if connection_check():
|
if connection_check():
|
||||||
@@ -113,6 +93,119 @@ class MyFrame(wx.Frame):
|
|||||||
self.message_field.SetValue("")
|
self.message_field.SetValue("")
|
||||||
|
|
||||||
|
|
||||||
|
class StartFrame(wx.Frame):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(parent=None, title='Enter Name', size=Constants.minimum_window_size)
|
||||||
|
self.panel = wx.Panel(self)
|
||||||
|
self.app = parent
|
||||||
|
# Create text field with suggestion text
|
||||||
|
text = wx.StaticText(self.panel, label='Enter name:')
|
||||||
|
self.name_field = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER, value='')
|
||||||
|
|
||||||
|
# Create submit button
|
||||||
|
submit_button = wx.Button(self.panel, label='Submit')
|
||||||
|
submit_button.Bind(wx.EVT_BUTTON, self.on_submit)
|
||||||
|
self.name_field.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter)
|
||||||
|
|
||||||
|
# Add text field and submit button to vertical sizer
|
||||||
|
vertical_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
vertical_sizer.Add(text, 0, wx.ALL, 5)
|
||||||
|
vertical_sizer.Add(self.name_field, 0, wx.EXPAND | wx.ALL, 5)
|
||||||
|
vertical_sizer.Add(submit_button, 0, wx.ALL | wx.CENTER, 5)
|
||||||
|
|
||||||
|
self.panel.SetSizer(vertical_sizer)
|
||||||
|
self.Show()
|
||||||
|
|
||||||
|
def on_submit(self, event):
|
||||||
|
message = self.name_field.GetValue()
|
||||||
|
if not message:
|
||||||
|
print("You didn't enter anything!")
|
||||||
|
else:
|
||||||
|
self.api_call(f"lobby join {message}")
|
||||||
|
|
||||||
|
def on_text_enter(self, event):
|
||||||
|
self.on_submit(event)
|
||||||
|
|
||||||
|
def show_list_view(self, event):
|
||||||
|
list_frame = LobbyFrame(self.app)
|
||||||
|
list_frame.Show()
|
||||||
|
|
||||||
|
# Refresh the layout of the original panel
|
||||||
|
self.Hide()
|
||||||
|
|
||||||
|
def api_call(self, message):
|
||||||
|
if connection_check():
|
||||||
|
self.app.parse_response(send(message))
|
||||||
|
self.name_field.SetValue("")
|
||||||
|
|
||||||
|
class LobbyFrame(wx.Frame):
|
||||||
|
def __init__(self, app):
|
||||||
|
super().__init__(parent=None, title='VCK Online Lobby', size=(250, 300))
|
||||||
|
self.app = app
|
||||||
|
self.panel = wx.Panel(self)
|
||||||
|
self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
|
# Create the list control and columns
|
||||||
|
self.list_ctrl = wx.ListCtrl(self.panel, style=wx.LC_REPORT)
|
||||||
|
self.list_ctrl.InsertColumn(0, "Player Name")
|
||||||
|
self.list_ctrl.InsertColumn(1, "Ready Status", format=wx.LIST_FORMAT_RIGHT)
|
||||||
|
self.get_lobby_status()
|
||||||
|
# Create the ready button
|
||||||
|
ready_button = wx.Button(self.panel, label="Ready Up")
|
||||||
|
ready_button.Bind(wx.EVT_BUTTON, self.on_ready_up)
|
||||||
|
|
||||||
|
# Add the list control and ready button to the vertical sizer
|
||||||
|
self.vertical_sizer.Add(self.list_ctrl, 1, wx.ALL | wx.EXPAND, 5)
|
||||||
|
self.vertical_sizer.Add(ready_button, 0, wx.ALL | wx.CENTER, 5)
|
||||||
|
self.panel.SetSizer(self.vertical_sizer)
|
||||||
|
self.SetMinSize(Constants.minimum_window_size)
|
||||||
|
|
||||||
|
# Bind the size event to adjust the column widths
|
||||||
|
self.Bind(wx.EVT_SIZE, self.on_size)
|
||||||
|
self.Bind(wx.EVT_CLOSE, self.on_close)
|
||||||
|
|
||||||
|
self.Show()
|
||||||
|
self.timer = wx.Timer(self)
|
||||||
|
self.Bind(wx.EVT_TIMER, self.get_lobby_status, self.timer)
|
||||||
|
self.timer.Start(1000)
|
||||||
|
|
||||||
|
def on_size(self, event):
|
||||||
|
# Calculate the width of each column based on the width of the list control
|
||||||
|
width = self.list_ctrl.GetSize()[0]
|
||||||
|
col_width = width // 2
|
||||||
|
self.list_ctrl.SetColumnWidth(0, col_width)
|
||||||
|
self.list_ctrl.SetColumnWidth(1, col_width)
|
||||||
|
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
def get_lobby_status(self, event=None):
|
||||||
|
if connection_check():
|
||||||
|
self.app.parse_response(send("lobby get_status"))
|
||||||
|
# Clear the list control
|
||||||
|
self.list_ctrl.DeleteAllItems()
|
||||||
|
|
||||||
|
# Populate the list control with the contents of the lobby
|
||||||
|
for index, player in enumerate(self.app.lobby):
|
||||||
|
self.list_ctrl.InsertItem(index, player['name'])
|
||||||
|
self.list_ctrl.SetItem(index, 1, "Ready" if player['is_ready'] else "Not Ready")
|
||||||
|
|
||||||
|
def on_ready_up(self, event):
|
||||||
|
for player in self.app.lobby:
|
||||||
|
if player['player_id'] == self.app.player_id:
|
||||||
|
if player['is_ready']:
|
||||||
|
if connection_check():
|
||||||
|
self.app.parse_response(send(f"lobby unready {self.app.player_id}"))
|
||||||
|
else:
|
||||||
|
if connection_check():
|
||||||
|
self.app.parse_response(send(f"lobby ready {self.app.player_id}"))
|
||||||
|
break
|
||||||
|
|
||||||
|
def on_close(self, event):
|
||||||
|
self.app.parse_response(send(f"lobby leave {self.app.player_id}"))
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def connection_check():
|
def connection_check():
|
||||||
try:
|
try:
|
||||||
response = send("connection_check")
|
response = send("connection_check")
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ class Card:
|
|||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self, name, player_id):
|
def __init__(self, player_id):
|
||||||
self.player_id = player_id
|
self.player_id = player_id
|
||||||
self.name = name
|
# self.name = name
|
||||||
self.owned_starters = []
|
self.owned_starters = []
|
||||||
self.owned_citizens = []
|
self.owned_citizens = []
|
||||||
self.owned_domains = []
|
self.owned_domains = []
|
||||||
@@ -416,7 +416,7 @@ class Game:
|
|||||||
grouped_monsters[area] = [monster]
|
grouped_monsters[area] = [monster]
|
||||||
# Reverse the order of each group by monster_order
|
# Reverse the order of each group by monster_order
|
||||||
for area, monsters in grouped_monsters.items():
|
for area, monsters in grouped_monsters.items():
|
||||||
monsters.sort(key=lambda monster: monster.order, reverse=True)
|
monsters.sort(key=lambda item: item.order, reverse=True)
|
||||||
areas = list(grouped_monsters.keys())
|
areas = list(grouped_monsters.keys())
|
||||||
chosen_areas = random.sample(areas, 5)
|
chosen_areas = random.sample(areas, 5)
|
||||||
for i, area in enumerate(chosen_areas):
|
for i, area in enumerate(chosen_areas):
|
||||||
@@ -469,7 +469,7 @@ class Game:
|
|||||||
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):
|
for i, player in enumerate(self.player_list):
|
||||||
print(
|
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}']}")
|
f"Player {i + 1}: {[f'{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)}")
|
||||||
|
|||||||
44
server.py
44
server.py
@@ -37,18 +37,26 @@ class ServerVCKO:
|
|||||||
self.lobby.append(joining_player)
|
self.lobby.append(joining_player)
|
||||||
message = f"lobby joined {joining_player_id}"
|
message = f"lobby joined {joining_player_id}"
|
||||||
conn.send(message.encode(Constants.text_format))
|
conn.send(message.encode(Constants.text_format))
|
||||||
elif full_command[1] == "get_status":
|
elif full_command[1] == "leave" and len(full_command) > 2:
|
||||||
lobby_data = []
|
temp_lobby = []
|
||||||
for lobby_member in self.lobby:
|
for player in self.lobby:
|
||||||
player_dict = {
|
if player.player_id != full_command[2]:
|
||||||
"name": lobby_member.name,
|
temp_lobby.append(player)
|
||||||
"player_id": lobby_member.player_id,
|
self.lobby = temp_lobby
|
||||||
"is_ready": lobby_member.is_ready
|
self.send_lobby_state(conn)
|
||||||
}
|
elif full_command[1] == "get_status" and len(full_command) == 2:
|
||||||
lobby_data.append(player_dict)
|
self.send_lobby_state(conn)
|
||||||
json_data = json.dumps(lobby_data)
|
elif full_command[1] == "ready" and len(full_command) > 2:
|
||||||
print(json_data)
|
for player in self.lobby:
|
||||||
conn.send(json_data.encode(Constants.text_format))
|
if player.player_id == full_command[2]:
|
||||||
|
player.is_ready = True
|
||||||
|
self.send_lobby_state(conn)
|
||||||
|
elif full_command[1] == "unready" and len(full_command) > 2:
|
||||||
|
for player in self.lobby:
|
||||||
|
if player.player_id == full_command[2]:
|
||||||
|
player.is_ready = False
|
||||||
|
|
||||||
|
self.send_lobby_state(conn)
|
||||||
else:
|
else:
|
||||||
conn.send("invalid message".encode(Constants.text_format))
|
conn.send("invalid message".encode(Constants.text_format))
|
||||||
case _:
|
case _:
|
||||||
@@ -66,6 +74,18 @@ class ServerVCKO:
|
|||||||
thread.start()
|
thread.start()
|
||||||
print(f"Active threads: {threading.active_count() - 1}")
|
print(f"Active threads: {threading.active_count() - 1}")
|
||||||
|
|
||||||
|
def send_lobby_state(self, conn):
|
||||||
|
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)
|
||||||
|
response = f"lobby state {json.dumps(lobby_data)}"
|
||||||
|
conn.send(response.encode(Constants.text_format))
|
||||||
|
|
||||||
|
|
||||||
class LobbyMember:
|
class LobbyMember:
|
||||||
def __init__(self, player_name, player_id):
|
def __init__(self, player_name, player_id):
|
||||||
|
|||||||
@@ -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 = "base2" # base1, base2, shadowvale, flamesandfrost, crimsonseas, shuffled
|
citizen_set = "base1" # base1, base2, shadowvale, flamesandfrost, crimsonseas, shuffled
|
||||||
game_board = Game(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