123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- from flask_login import UserMixin
- from werkzeug.security import generate_password_hash, check_password_hash
- from flask_sqlalchemy import SQLAlchemy
- from sqlalchemy.orm import relationship
- import random
- from belote_jeu import cards, N_PLAYERS, colors, winner, N_TURN
- db = SQLAlchemy()
- levels_users = {'Inactive':0, 'Simple user':1, 'Can create games':2, 'Can manage games':8, 'Can manage simple users': 9, 'Admin':10}
- #######################################################################
- # User class #
- #######################################################################
- class User(UserMixin, db.Model):
- """Model for user accounts."""
- __tablename__ = 'users'
- login = db.Column(db.String(100),
- primary_key=True)
- name = db.Column(db.String(100),
- nullable=False,
- unique=False)
- password = db.Column(db.String(100),
- primary_key=False,
- unique=False,
- nullable=False)
- level = db.Column(db.Integer, default=1)
- last_login = db.Column(db.DateTime)
- def set_password(self, password):
- """Create hashed password."""
- self.password = generate_password_hash(password, method='sha256')
- def check_password(self, password):
- """Check hashed password."""
- return check_password_hash(self.password, password)
- def get_id(self):
- return self.login
- def __repr__(self):
- return '<User {}>'.format(self.login)
- #######################################################################
- # Game class #
- #######################################################################
- class Game(db.Model):
- __tablename__ = 'games'
- id = db.Column(db.Integer,
- primary_key=True)
- name = db.Column(db.String(200))
- players = relationship("Player")
- turn = db.Column(db.Integer, default=-8)
- atout = db.Column(db.String(1))
- preneur = db.Column(db.String(100))
- admin = db.Column(db.String(100), db.ForeignKey('users.login'))
- cards_to_distribute = db.Column(db.String(200))
- first_player = db.Column(db.Integer)
- start = db.Column(db.Boolean, default=False)
- last_played = db.Column(db.String(20))
- played = db.Column(db.String(20))
- fixplayers = db.Column(db.Boolean, default=False)
- points_0 = db.Column(db.Integer, default=0)
- points_1 = db.Column(db.Integer, default=0)
- cumul_0 = db.Column(db.Integer, default=0)
- cumul_1 = db.Column(db.Integer, default=0)
- partie = db.Column(db.Integer, default=1)
- distributeur = db.Column(db.Integer, default=0)
- def start_game(self, ordered_players):
- # Ordering players
- if self.fixplayers and not self.start:
- i=0
- if ordered_players is not None:
- for op in ordered_players:
- player = Player.query.filter_by(game=self.id, user=op).first()
- if player is not None:
- player.nr = i
- i+=1
- for p in self.players:
- if p.nr is None or p.nr<0:
- p.nr = i
- i+=1
- db.session.commit()
- self.start = True
- self.first_player = 0
- self.distribute()
- db.session.commit()
- return True
- return False
- def fix_players(self):
- if self.can_start():
- self.fixplayers = True
- db.session.commit()
- def distribute(self):
- ___cartes = random.sample(cards, k=len(cards))
- for i in range(len(self.players)):
- self.players[i].cards = ','.join(___cartes[5*i:5*(i+1)])
- self.played = ___cartes[5*(i+1)]
- self.cards_to_distribute = ','.join(___cartes[5*(i+1)+1:])
- def authorized(self, user):
- for p in self.players:
- if user.login == p.user:
- return True
- return False
-
- def isadmin(self, user):
- return user.login == self.admin
- def serialize_state_anonymous(self):
- r = {}
- r['players'] = self.get_ordered_players()
- r['playersinfo'] = {}
- for p in self.players:
- r['playersinfo'][p.user] = User.query.get(p.user).name
- r['atout'] = self.atout
- r['preneur'] = self.preneur
- r['last_played'] = self.last_played.split(',') if self.last_played is not None else []
- r['played'] = self.played.split(',') if self.played is not None else []
- r['turn'] = self.turn
- r['first_player'] = self.first_player
- r['points'] = [self.points_0, self.points_1]
- r['cumul'] = [self.cumul_0, self.cumul_1]
- r['partie'] = self.partie
- r['admin'] = self.admin
- r['distributeur'] = self.distributeur
- return r
- def serialize_state(self, user):
- r = self.serialize_state_anonymous()
- r['nr'] = self.get_nr(user)
- cards = self.get_player(user).cards
- r['cards'] = cards.split(',') if cards is not None else []
- return r
- def get_ordered_players(self):
- r = {}
- for p in self.players:
- r[p.nr] = p.user
- r2 = []
- for i in range(N_PLAYERS):
- r2.append(r[i] if i in r else None)
- return r2
- def get_nr(self, user):
- p = self.get_player(user)
- if p is not None :
- return p.nr
- else:
- return -1
- def get_player(self, user):
- if not isinstance(user, str):
- user = user.login
- return Player.query.filter_by(game=self.id, user=user).first()
- def can_join(self, user):
- if self.authorized(user):
- return True
- if not self.fixplayers and len(self.players) < N_PLAYERS:
- return True
- return False
- def can_start(self):
- if len(self.players)==N_PLAYERS:
- return True
- return False
- def join(self, user):
- if not self.fixplayers and not self.authorized(user):
- p = Player(game=self.id, user=user.login)
- db.session.add(p)
- db.session.commit()
- def leave(self, user):
- if not self.fixplayers:
- for p in self.players:
- if isinstance(user, str) and user != self.admin or hasattr(user, 'login') and user.login != self.admin:
- if isinstance(user, str) and user == p.user or hasattr(user, 'login') and user.login == p.user:
- db.session.delete(p)
- db.session.commit()
- return True
- return False
- def get_players(self):
- r = []
- for p in self.players:
- user = User.query.get(p.user)
- r.append({'username':user.login, 'name':user.name})
- return r
-
- def tour_choix(self, atout, user):
- if (self.turn + self.first_player) % N_PLAYERS == self.get_nr(user):
- self.turn += 1
- if atout is not None and atout in colors:
- self.atout = atout
- self.preneur = user.login
- self.turn = 0
- self.distribute_restant()
- db.session.commit()
- return True
- return False
- def distribute_restant(self):
- todistribute = self.cards_to_distribute.split(',')
- for pn in self.get_ordered_players():
- p = self.get_player(pn)
- if pn == self.preneur:
- p.cards += ',' + ','.join(todistribute[:2])
- p.cards += ',' + self.played
- todistribute = todistribute[2:]
- else:
- p.cards += ',' + ','.join(todistribute[:3])
- todistribute = todistribute[3:]
- self.cards_to_distribute = ''
- self.played = None
- def tour_jeu(self, carte, user):
- if (self.turn + self.first_player) % N_PLAYERS == self.get_nr(user):
- winnr = -1
- self.turn += 1
- if self.played is None or self.played == '':
- self.played = carte
- else:
- self.played += ',' + carte
- if self.turn % N_PLAYERS == 0 :
- winnr, points = winner(self.played, self.atout)
- if (self.first_player + winnr)%2 == 0:
- self.points_0 += points
- else:
- self.points_1 += points
- self.last_played = self.played
- if len(self.cards_to_distribute)>1:
- self.cards_to_distribute += ','
- self.cards_to_distribute += self.played
- self.played = None
- self.first_player = (self.first_player + winnr)%4
- if self.turn == N_TURN*N_PLAYERS: # Dix de der, chute, belote et capote !
- # Dix de der
- if self.first_player%2 == 0:
- self.points_0 += 10
- else:
- self.points_1 += 10
-
- # Belote possible
- winnr = self.distributeur
- belote =-1
- belote_0 = 0
- belote_1 = 0
- ccc = self.cards_to_distribute.split(',')
- for i in range(N_TURN):
- cccc = ccc[i*N_PLAYERS:(i+1)*N_PLAYERS]
- if 'R'+self.atout in cccc:
- if belote>=0:
- if (cccc.index('R'+self.atout) + winnr)%4 == belote %4:
- if belote %2 ==0:
- self.points_0 += 20
- belote_0 = 20
- else:
- self.points_1 += 20
- belote_1 = 20
- else:
- belote = winnr + cccc.index('R'+self.atout)
- if 'D'+self.atout in cccc:
- if belote>=0:
- if (cccc.index('D'+self.atout) + winnr)%4 == belote %4:
- if belote %2 ==0:
- self.points_0 += 20
- belote_0 = 20
- else:
- self.points_1 += 20
- belote_1 = 20
- else:
- belote = winnr + cccc.index('D'+self.atout)
- win, xxx = winner(cccc, self.atout)
- winnr = win+winnr
- # Capote
- if self.points_0 >= 162 or self.points_1 >= 162:
- winequipe = 0 if self.points_0 >= 162 else 1
- # Capote possible.
- winnr = self.distributeur
- ccc = self.cards_to_distribute.split(',')
- for i in range(N_TURN):
- win, xxx = winner(ccc[i*N_PLAYERS:(i+1)*N_PLAYERS], self.atout)
- winnr = win+winnr
- if winnr % 2 != winequipe:
- break
- else:
- if winequipe == 0:
- self.points_0 += 90
- else:
- self.points_1 += 90
- # Chute
- if self.get_player(self.preneur).nr %2 ==0 and self.points_0 < self.points_1:
- self.points_0 = belote_0
- self.points_1 = 162 + belote_1
- if self.get_player(self.preneur).nr %2 ==1 and self.points_1 < self.points_0:
- self.points_0 = 162 + belote_0
- self.points_1 = belote_1
- # Retirer la carte du jeu !
- p = self.get_player(user)
- ccc = p.cards
- ccc = ccc.split(',')
- ccc.remove(carte)
- p.cards = ','.join(ccc)
- db.session.commit()
- return True, winnr
- return False, -1
-
- def restart_jeu(self):
- if (self.turn==0 and (self.atout=='' or self.atout is None)) or self.turn==N_TURN*N_PLAYERS:
- if self.turn>0:
- self.partie +=1
- self.turn = -8
- self.atout = None
- self.preneur = None
- self.last_played = None
- self.played = None
- self.cumul_0 += self.points_0
- self.cumul_1 += self.points_1
- self.points_0 = 0
- self.points_1 = 0
- if self.distributeur <3:
- self.distributeur += 1
- else:
- self.distributeur = 0
- self.first_player = self.distributeur
- self.distribute()
- db.session.commit()
- return True
- return False
- #######################################################################
- # Player class #
- #######################################################################
- class Player(db.Model):
- __tablename__ = 'players'
- id = db.Column(db.Integer,
- primary_key=True)
- game = db.Column(db.Integer, db.ForeignKey('games.id'))
- user = db.Column(db.String(100), db.ForeignKey('users.login'))
- cards = db.Column(db.String(40))
- nr = db.Column(db.Integer, default=-1)
|