Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
jporubci committed Jun 1, 2023
1 parent 5f81d1f commit 1b3cabd
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 89 deletions.
6 changes: 1 addition & 5 deletions client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
# os.getlogin() to get username
import os

# To send and receive data structures via messages
import json

# time.time_ns() to date messages
import time

Expand All @@ -19,7 +16,6 @@
class Client:
def __init__(self):
self.name = os.getlogin()
self.settings = Settings()

self.host_name = None
self.client_names = None
Expand Down Expand Up @@ -92,7 +88,7 @@ async def ping_coro(self):
while not self.shutdown_flag.is_set():

# Wait for PING_INTERVAL seconds
await asyncio.sleep(self.settings.PING_INTERVAL)
await asyncio.sleep(Settings().PING_INTERVAL)

# Ping host
if (await send_message(self.writer, {'command': 'ping'}) == 0):
Expand Down
17 changes: 17 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,20 @@ def __init__(self):
self.DELAY = 1
self.MIN_CLIENTS = 2
self.MAX_CLIENTS = 2


class Constants:
def __init__(self):
self.NUM_PLAYERS = 3
self.STARTING_HAND_SIZE = 12

self.RANKS = [
'A', '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'J', 'Q', 'K'
]

self.CLUB = '\U00002660'
self.SPADE = '\U00002663'
self.HEART = '\U00002665'
self.DIAMOND = '\U00002666'
self.SUITS = [ CLUB, SPADE, HEART, DIAMOND ]
15 changes: 7 additions & 8 deletions host.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# os.getlogin() to get username
import os

# To send and receive data structures via messages
# To send formatted registration messages
import json

# time.time_ns() to date messages
Expand All @@ -25,7 +25,6 @@
class Host:
def __init__(self):
self.name = os.getlogin()
self.settings = Settings()
self.server = None
self.port = None

Expand All @@ -41,13 +40,13 @@ def __init__(self):

# Register with catalog server
def register(self):
socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(str(json.dumps({'type': self.settings.ENTRY_TYPE, 'owner': self.name, 'port': self.port, 'num_clients': len(self.clients)})).encode(), (self.settings.CATALOG_SERVER[:-5], int(self.settings.CATALOG_SERVER[-4:])))
socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(str(json.dumps({'type': Settings().ENTRY_TYPE, 'owner': self.name, 'port': self.port, 'num_clients': len(self.clients)})).encode(), (Settings().CATALOG_SERVER[:-5], int(Settings().CATALOG_SERVER[-4:])))


# Register with catalog server every REGISTER_INTERVAL seconds
async def register_coro(self):
while not self.shutdown_flag.is_set():
await asyncio.sleep(self.settings.REGISTER_INTERVAL)
await asyncio.sleep(Settings().REGISTER_INTERVAL)
self.register()


Expand All @@ -59,7 +58,7 @@ async def handle_client(self, reader, writer):

# Check if lobby is not full
async with self.clients_lock:
if not (full := len(self.clients) == self.settings.MAX_CLIENTS):
if not (full := len(self.clients) == Settings().MAX_CLIENTS):
# Accept new client
join_time = time.time_ns() / 1000000000.0
self.clients[(reader, writer)] = {
Expand Down Expand Up @@ -163,8 +162,8 @@ async def purge_coro(self):
while not self.shutdown_flag.is_set():

# Wait for PING_INTERVAL seconds
await asyncio.sleep(self.settings.PING_INTERVAL)
stale_time = time.time_ns() / 1000000000.0 - (self.settings.PING_INTERVAL + self.settings.DELAY)
await asyncio.sleep(Settings().PING_INTERVAL)
stale_time = time.time_ns() / 1000000000.0 - (Settings().PING_INTERVAL + Settings().DELAY)

async with self.clients_lock:
# Record the starting number of clients before the purge
Expand Down Expand Up @@ -228,4 +227,4 @@ async def shutdown(self):
self.clients_lock.release()

# Register a lie to make lobby disappear
socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(str(json.dumps({'type': self.settings.ENTRY_TYPE, 'owner': self.name, 'port': self.port, 'num_clients': self.settings.MAX_CLIENTS + 1})).encode(), (self.settings.CATALOG_SERVER[:-5], int(self.settings.CATALOG_SERVER[-4:])))
socket.socket(socket.AF_INET, socket.SOCK_DGRAM).sendto(str(json.dumps({'type': Settings().ENTRY_TYPE, 'owner': self.name, 'port': self.port, 'num_clients': Settings().MAX_CLIENTS + 1})).encode(), (Settings().CATALOG_SERVER[:-5], int(Settings().CATALOG_SERVER[-4:])))
11 changes: 5 additions & 6 deletions lobby.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,6 @@ def __init__(self, stdscr):
self.input_buffer = ''

self.name = os.getlogin()
self.settings = Settings()

self.curr_state = 'MENU'
self.lobbies = None
Expand All @@ -495,7 +494,7 @@ def __init__(self, stdscr):
async def get_lobbies(self):
# Try to get catalog within time limit
try:
async with asyncio.timeout(self.settings.DELAY):
async with asyncio.timeout(Settings().DELAY):
response = await self._get_catalog()

except TimeoutError:
Expand All @@ -507,7 +506,7 @@ async def get_lobbies(self):


async def _get_catalog(self):
http_conn = http.client.HTTPConnection(self.settings.CATALOG_SERVER)
http_conn = http.client.HTTPConnection(Settings().CATALOG_SERVER)
http_conn.request('GET', '/query.json')
response = http_conn.getresponse()
http_conn.close()
Expand All @@ -525,7 +524,7 @@ def _parse_catalog(self, response):
if all(key in entry for key in ('type', 'lastheardfrom', 'num_clients', 'address', 'port', 'owner')):

# If the entry is an open lobby (correct type, not stale, not full)
if entry['type'] == self.settings.ENTRY_TYPE and entry['lastheardfrom'] >= time.time_ns() / 1000000000.0 - self.settings.REGISTER_INTERVAL - self.settings.DELAY and entry['num_clients'] < self.settings.MAX_CLIENTS:
if entry['type'] == Settings().ENTRY_TYPE and entry['lastheardfrom'] >= time.time_ns() / 1000000000.0 - Settings().REGISTER_INTERVAL - Settings().DELAY and entry['num_clients'] < Settings().MAX_CLIENTS:

# Ensure entry is most recent entry of its kind
most_recent = True
Expand All @@ -548,9 +547,9 @@ def _parse_catalog(self, response):
def display_lobbies(self, indexed=False):
for i, lobby in enumerate(self.lobbies, start=1):
if indexed:
self.stdscr.addstr(f'{i}: {lobby["owner"]} - {lobby["address"]}:{lobby["port"]} [{lobby["num_clients"]}/{self.settings.MAX_CLIENTS}]\n')
self.stdscr.addstr(f'{i}: {lobby["owner"]} - {lobby["address"]}:{lobby["port"]} [{lobby["num_clients"]}/{Settings().MAX_CLIENTS}]\n')
else:
self.stdscr.addstr(f'{lobby["owner"]} - {lobby["address"]}:{lobby["port"]} [{lobby["num_clients"]}/{self.settings.MAX_CLIENTS}]\n')
self.stdscr.addstr(f'{lobby["owner"]} - {lobby["address"]}:{lobby["port"]} [{lobby["num_clients"]}/{Settings().MAX_CLIENTS}]\n')


def start_lobby(stdscr):
Expand Down
67 changes: 67 additions & 0 deletions server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
# table.py

# To shuffle the deck of cards
import secrets

# To get game constants
from config import Constants

class Card:
def __init__(self, rank, suit):
self.rank = rank
self.suit = suit
self.points = min(max(1, Constants().RANKS.index(self.rank)), 10)


class Player:
def __init__(self, hand):
self.hand = hand
self.melds = list()
self.score = None


class Server:
def __init__(self):
self.deck = self._init_deck()
self.discard = list()
self.order = self._init_order()
self.players = self._init_players()
self.last_draw = None


# Returns a standard 52-card shuffled deck
def _init_deck():
temp_deck = [Card(rank, suit) for rank in Constants().RANKS for suit in Constants().SUITS]
deck = list()
while temp_deck:
card = secrets.choice(temp_deck)
deck.append(card)
temp_deck.remove(card)

return deck


# Returns a random order of player indices
def _init_order(self):
temp_order = [i for i in range(Constants().NUM_PLAYERS)]
order = list()
while temp_order:
index = secrets.choice(temp_order)
order.append(index)
temp_order.remove(index)

return order


# Deal cards to players
def _init_players()
players = [Player() for _ in range(Constants().NUM_PLAYERS)]
for _ in range(Constants().STARTING_HAND_SIZE):
for i in self.order:
players[i].hand.append(self.deck.pop())

for player in players:
player.score = sum((card.points for card in player.hand))

return players
73 changes: 3 additions & 70 deletions tong-its.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,15 @@
# Import lobby.py
import lobby

# To shuffle the deck of cards
import secrets

### CONSTANTS ###

STARTING_HAND_SIZE = 12

RANKS = [
'A', '2', '3', '4', '5', '6', '7',
'8', '9', '10', 'J', 'Q', 'K'
]

CLUB = '\U00002660'
SPADE = '\U00002663'
HEART = '\U00002665'
DIAMOND = '\U00002666'

SUITS = [ CLUB, SPADE, HEART, DIAMOND ]

#END OF CONSTANTS


### OBJECTS ###

#points = min(max(1, RANKS.index(self.rank)), 10)


class Deck:
def __init__(self):
self.deck = [(rank, suit) for rank in RANKS for suit in SUITS]

def shuffle(self):
deck_copy = self.deck.copy()
self.deck.clear()

while deck_copy:
card = secrets.choice(deck_copy)
self.deck.append(card)
deck_copy.remove(card)


def draw(self):
if len(self.deck):
return self.deck.pop()


class Discard:
def __init__(self):
self.discard = list()

def put(self, card):
if card:
self.discard.append(card)
return 1
else:
return 0

def draw(self):
if len(self.discard):
return self.discard.pop()

#END OF OBJECTS


ret_val = lobby.main()

# Host
if type(ret_val) is dict:
print('Host')

while True:
pass
#


# Client
elif type(ret_val) is tuple:
print('Client')

while True:
pass
#

0 comments on commit 1b3cabd

Please sign in to comment.