2020-03-14 17:54:35 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import functools
import pickle
import socket
import random
import sys
import uuid
from opale . computer import Computer
from opale . game import Game
s = socket . socket ( socket . AF_INET , socket . SOCK_STREAM )
s . setsockopt ( socket . SOL_SOCKET , socket . SO_REUSEADDR , 1 )
try :
s . bind ( ( " 0.0.0.0 " , 54321 ) )
except socket . error as msg :
print ( ' Bind failed. Error Code : ' + str ( msg [ 0 ] ) + ' Message ' + msg [ 1 ] )
sys . exit ( )
print ( ' Socket bind complete ' )
s . listen ( 2 )
print ( ' Socket now listening ' )
try :
with open ( ' saved_games.pickle ' , ' rb ' ) as f :
games = pickle . load ( f )
except :
print ( " Unable to load ' saved_games.pickle ' " )
games = { }
def writeSocket ( socket , string , * args ) :
if len ( args ) == 1 and args [ 0 ] == None :
socket . send ( str ( string ) . encode ( ) )
elif len ( args ) > 0 :
socket . send ( ( string % args ) . encode ( ) + b " \n " )
else :
socket . send ( str ( string ) . encode ( ) + b " \n " )
def readSocket ( socket , string ) :
socket . send ( str ( string ) . encode ( ) )
s = socket . recv ( 1024 ) . decode ( ) . strip ( )
return s . split ( " \n " ) [ - 1 ] . strip ( )
2020-03-15 10:25:36 +00:00
watchers = [ ]
2020-03-14 17:54:35 +00:00
while True :
try :
connP1 , addrP1 = s . accept ( )
print ( ' Connected with ' + addrP1 [ 0 ] + ' : ' + str ( addrP1 [ 1 ] ) )
connP1 . send ( " Hey! Welcome to Opale game. What ' s your name? \n > " . encode ( ) )
print ( ' Asking Player1 name... ' )
nameP1 = connP1 . recv ( 1024 ) . decode ( ) . strip ( )
2020-03-15 10:25:36 +00:00
if nameP1 == " watcher " :
print ( " new Watcher " )
watchers . append ( connP1 )
connP1 . send ( ( " Welcome! You ' ll watch futher games. Wait for one... :) \n " ) . encode ( ) )
continue
else :
connP1 . send ( ( " Welcome \033 [93m %s \033 [0m! We are waiting for a second player... \n " % nameP1 ) . encode ( ) )
connP1 . send ( " \n \n Would you like to load a saved game? (leave blank and press ENTER to load a new game) \n > " . encode ( ) )
connP2 , addrP2 = s . accept ( )
print ( ' Connected with ' + addrP2 [ 0 ] + ' : ' + str ( addrP2 [ 1 ] ) )
connP2 . send ( " Hey! Welcome to Opale game. What ' s your name? \n > " . encode ( ) )
print ( ' Asking Player2 name... ' )
nameP2 = " "
while len ( nameP2 ) == 0 or nameP2 == nameP1 :
if nameP2 == nameP1 :
connP2 . send ( " Name conflict! Please choose another name: " . encode ( ) )
nameP2 = connP2 . recv ( 1024 ) . decode ( ) . strip ( )
connP2 . send ( ( " Welcome \033 [93m %s \033 [0m! We are ready to play. You ' ll fight against \033 [93m %s \033 [0m! \n " % ( nameP2 , nameP1 ) ) . encode ( ) )
connP1 . send ( ( " \n You ' ll fight against \033 [93m %s \033 [0m " % nameP2 ) . encode ( ) )
saved_games = [ k for k in games . keys ( ) if ( games [ k ] . player1 . name == nameP1 and games [ k ] . player2 . name == nameP2 ) or ( games [ k ] . player1 . name == nameP2 and games [ k ] . player2 . name == nameP1 ) ]
if len ( saved_games ) :
connP1 . send ( ( " \n Here is a list of saved games together: %s \n " % saved_games ) . encode ( ) )
2020-03-14 17:54:35 +00:00
choice = " sentinel "
erchoice = " "
while len ( choice ) != 0 and choice not in games :
if choice != " sentinel " :
erchoice = choice
connP1 . send ( ( " No game exists with this identifier. Retry (or type the same choice to use it as seed): \n > " ) . encode ( ) )
choice = connP1 . recv ( 1024 ) . decode ( ) . strip ( )
if erchoice == choice :
break
connP1 . send ( ( chr ( 27 ) + " [2J " ) . encode ( ) )
connP2 . send ( ( chr ( 27 ) + " [2J " ) . encode ( ) )
if choice not in games :
if len ( choice ) == 0 :
choice = str ( uuid . uuid1 ( ) )
random . seed ( choice )
game = Game ( nameP1 , nameP2 )
games [ choice ] = game
connP1 . send ( ( " \n \n You entered a new game. \n Save the id of the room if you loose the connection for any reason: %s \n " % choice ) . encode ( ) )
connP2 . send ( ( " \n \n You entered a new game. \n Save the id of the room if you loose the connection for any reason: %s \n " % choice ) . encode ( ) )
print ( " Play new game between %s and %s : %s " % ( nameP1 , nameP2 , choice ) )
else :
game = games [ choice ]
if game . player1 . name == nameP2 or game . player2 . name == nameP1 :
game . player2 , game . player1 = game . player1 , game . player2
game . round - = 1
game . player1 . name = nameP1
game . player2 . name = nameP2
connP1 . send ( ( " You entered a saved game ( %s ); \033 [93m %s \033 [0m takes the place of \033 [94m %s \033 [0m, \033 [93m %s \033 [0m the place of \033 [94m %s \033 [0m. \n " % ( choice , nameP1 , game . player1 . name , nameP2 , game . player2 . name ) ) . encode ( ) )
connP2 . send ( ( " You entered a saved game ( %s ); \033 [93m %s \033 [0m takes the place of \033 [94m %s \033 [0m, \033 [93m %s \033 [0m the place of \033 [94m %s \033 [0m. \n " % ( choice , nameP1 , game . player1 . name , nameP2 , game . player2 . name ) ) . encode ( ) )
connP1 . send ( ( " \n \n Welcome back! We are at round %d . \033 [96m %d citie(s) discovered. \033 [0m \033 [93m %s \033 [0m collected %d cards, you collected %d card(s). \n " % ( game . round / / 2 , game . board . roundCity , game . player2 . name , len ( game . player2 . défausse ) , len ( game . player1 . défausse ) ) ) . encode ( ) )
connP2 . send ( ( " \n \n Welcome back! We are at round %d . \033 [96m %d citie(s) discovered. \033 [0m \033 [93m %s \033 [0m collected %d cards, you collected %d card(s). \n " % ( game . round / / 2 , game . board . roundCity , game . player1 . name , len ( game . player1 . défausse ) , len ( game . player2 . défausse ) ) ) . encode ( ) )
game . player1 . print = functools . partial ( writeSocket , connP1 )
game . player2 . print = functools . partial ( writeSocket , connP2 )
game . player1 . input = functools . partial ( readSocket , connP1 )
game . player2 . input = functools . partial ( readSocket , connP2 )
2020-03-15 10:25:36 +00:00
def printWatchers ( * args ) :
for w in watchers :
try :
writeSocket ( w , * args )
except :
try :
w . close ( )
except :
pass
watchers . remove ( w )
2020-03-14 17:54:35 +00:00
def printBoth ( * args ) :
game . player1 . print ( * args )
game . player2 . print ( * args )
2020-03-15 10:25:36 +00:00
printWatchers ( * args )
2020-03-14 17:54:35 +00:00
def play_turn ( ) :
2020-03-15 10:25:36 +00:00
printWatchers ( " \n \033 [1mCurrent player: \033 [0m \033 [93m %s \033 [0m \033 [95m %s \033 [0m " % ( game . current_player . name , " DRAGON " if game . current_player . dragonPetrified else " " ) )
2020-03-14 17:54:35 +00:00
game . current_player . print ( " \n \033 [1mCurrent player: \033 [0m \033 [93m %s \033 [0m \033 [95m %s \033 [0m " % ( game . current_player . name , " DRAGON " if game . current_player . dragonPetrified else " " ) )
game . current_partner . print ( " \n \033 [1mCurrent player: \033 [0m \033 [96m %s \033 [0m \033 [95m %s \033 [0m " % ( game . current_player . name , " DRAGON " if game . current_player . dragonPetrified else " " ) )
while True :
printBoth ( game . board )
game . current_player . print ( " \033 [1mHere is your hand currently: \033 [0m %s " % { i + 1 : game . current_player . hand [ i ] for i in range ( len ( game . current_player . hand ) ) } )
game . current_partner . print ( " \033 [1mHere is your hand currently: \033 [0m %s " % { i + 1 : game . current_partner . hand [ i ] for i in range ( len ( game . current_partner . hand ) ) } )
game . current_partner . print ( " \n =============:[ Please wait until \033 [1;96m " + game . current_player . name + " \033 [0m plays... :-) ]:============= \r " , None )
2020-03-15 10:25:36 +00:00
printWatchers ( " \n =============:[ Please wait until \033 [1;96m " + game . current_player . name + " \033 [0m plays... :-) ]:============= \r " , None )
2020-03-14 17:54:35 +00:00
icards = game . current_player . input ( " \n Choose one or more card to play: " )
pcards = map ( lambda x : int ( x ) , icards . split ( " " ) )
good = True
cards = [ ]
for card in pcards :
if card < = 0 or card > len ( game . current_player . hand ) :
game . current_player . print ( " \033 [91m %s is not a valid card. \033 [0m " % card )
good = False
break
else :
cards . append ( game . current_player . hand [ card - 1 ] )
if good :
try :
game . play_round ( * cards )
2020-03-15 10:25:36 +00:00
return cards
2020-03-14 17:54:35 +00:00
except Exception as e :
game . current_player . print ( " \033 [91m %s \033 [0m " % e )
while not game . isFinished ( ) :
with open ( ' saved_games.pickle ' , ' wb ' ) as f :
ip1 = game . player1 . input
del game . player1 . input
ip2 = game . player2 . input
del game . player2 . input
pp1 = game . player1 . print
del game . player1 . print
pp2 = game . player2 . print
del game . player2 . print
pickle . dump ( games , f , pickle . HIGHEST_PROTOCOL )
game . player1 . input = ip1
game . player2 . input = ip2
game . player1 . print = pp1
game . player2 . print = pp2
2020-03-15 10:25:36 +00:00
curRound = game . board . roundCity
hasDragon = game . current_player . dragonPetrified
2020-03-14 17:54:35 +00:00
try :
2020-03-15 10:25:36 +00:00
cards = play_turn ( )
2020-03-14 17:54:35 +00:00
except BrokenPipeError as e :
raise e
except Exception as e :
2020-03-15 10:25:36 +00:00
raise e
2020-03-14 17:54:35 +00:00
game . current_player . print ( " \033 [91mSorry, something goes wrong: ' %s ' . \033 [0m " % e )
pass
2020-03-15 10:25:36 +00:00
printBoth ( chr ( 27 ) + " [2J " )
game . current_player . print ( " \n \033 [93m %s \033 [0m plays: %s \n " % ( game . current_partner . name , cards ) )
printWatchers ( " \n \033 [93m %s \033 [0m plays: %s \n " % ( game . current_partner . name , cards ) )
game . current_partner . print ( " \n You played: %s \n " % ( cards ) )
if game . current_partner . dragonPetrified != hasDragon :
game . current_player . print ( " \n \033 [1;93m %s \033 [95m takes the petrified dragon! \033 [0m \n " % game . current_partner . name )
printWatchers ( " \n \033 [1;93m %s \033 [95m takes the petrified dragon! \033 [0m \n " % game . current_partner . name )
game . current_partner . print ( " \n \033 [95mYou take the petrified dragon! \033 [0m \n " )
if curRound != game . board . roundCity and game . board . roundCity < 3 :
game . current_player . print ( " \n \033 [1;93m %s \033 [96m discovers a new lost city! \033 [1m %d / %d \033 [0m \n " % ( game . current_partner . name , game . board . roundCity , 3 ) )
printWatchers ( " \n \033 [1;93m %s \033 [96m discovers a new lost city! \033 [1m %d / %d \033 [0m \n " % ( game . current_partner . name , game . board . roundCity , 3 ) )
game . current_partner . print ( " \n \033 [96mYou discover a new lost city! \033 [1m %d / %d \033 [0m \n " % ( game . board . roundCity , 3 ) )
2020-03-14 17:54:35 +00:00
if game . player1 . cantpioche :
printBoth ( " \n \033 [1;93m %s n ' a plus de pioche ! Last round \033 [0m " % game . player1 . name )
elif game . player2 . cantpioche :
printBoth ( " \n \033 [1;93m %s n ' a plus de pioche ! Last round \033 [0m " % game . player2 . name )
else :
printBoth ( " \n \033 [1;96mCité sous-marine découverte ! Last round \033 [0m " )
try :
play_turn ( )
except BrokenPipeError as e :
raise e
except Exception as e :
game . current_player . print ( " \033 [91mSorry, something goes wrong: ' %s ' . \033 [0m " % e )
pass
printBoth ( game . board )
printBoth ( " \n " )
printBoth ( " \033 [93m %s \033 [0m: \033 [1m %d \033 [0m pts " % ( game . current_player . name , game . current_player . get_score ( ) ) )
printBoth ( " \033 [93m %s \033 [0m: \033 [1m %d \033 [0m pts " % ( game . current_partner . name , game . current_partner . get_score ( ) ) )
del games [ choice ]
connP1 . send ( ( " \n \n Finished! See you next time " + nameP1 + " ! \n \n \n " ) . encode ( ) )
connP2 . send ( ( " \n \n Finished! See you next time " + nameP2 + " ! \n \n \n " ) . encode ( ) )
connP1 . close ( )
connP2 . close ( )
except BrokenPipeError as e :
print ( e )
finally :
try :
connP1 . send ( ( " \n Connection lost with the other player. Save the game id to continuer later (you were player 1): " + choice + " \n " ) . encode ( ) )
connP1 . close ( )
except :
pass
try :
connP2 . send ( ( " \n Connection lost with the other player. Save the game id to continuer later (you were player 2): " + choice + " \n " ) . encode ( ) )
connP2 . close ( )
except :
pass
s . close ( )