Compare commits

..

No commits in common. "master" and "v0.1.1" have entirely different histories.

77 changed files with 136 additions and 612 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "js-cardgame"]
path = js-cardgame
url = git@github.com:strupppi/js-cardgame.git

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

@ -1 +0,0 @@
Subproject commit 4d88b9198cb335414600aab691bbe1ae5edb590c

View File

@ -1,2 +0,0 @@
starlette~=0.12.13
responder~=2.0.5

View File

@ -1,17 +1,14 @@
# noinspection PyUnresolvedReferences
from app_instance import api
# noinspection PyUnresolvedReferences
from views.api_views import *
# noinspection PyUnresolvedReferences
from views.home import *
# noinspection PyUnresolvedReferences
from views.temp_css import *
# noinspection PyUnresolvedReferences
from views.player import *
# noinspection PyUnresolvedReferences
from views.gplayer import *
# noinspection PyUnresolvedReferences
from views.js_cardgame import *
# noinspection PyUnresolvedReferences
from views.control import *
api.add_route("/static", static=True)
api.add_route("/js", static=True)

View File

@ -1,25 +1,21 @@
#!/usr/bin/env python3
import random
import socket
import responder
from app_instance import api
from routes import *
import wiz_game
import argparse
def main():
print("main started")
parser = argparse.ArgumentParser()
parser.add_argument('--port', metavar='port', default=8001, type=int, help='the port to bind to')
parser.add_argument('--bindaddr', metavar='addr', default='127.0.0.1', help='the address to bind to')
args = parser.parse_args()
random.seed()
wiz_game.the_game.start_game()
api.run(port=args.port, address=args.bindaddr)
#api.run(port=8001, address="127.0.0.1")
api.run(port=8001, address="192.168.42.1")
exit(0)

View File

@ -22,12 +22,10 @@
Winner: {{trick_winner}} with Card {{highest_card}}
<a href="/control/next_trick/">start next trick</a>
{% endif %}
{% if round_finished %}
{% if hand_finished %}
Winner: {{trick_winner}} with Card {{highest_card}}
<a href="/control/next_round/">start next round</a>
<a href="/control/next_hand/">start next hand</a>
{% endif %}
<br>
<a href="/control/undo_last/">undo last card</a>
<!--
<ul>
<li>

View File

@ -1,206 +0,0 @@
{% extends "/shared/_layout.html" %}
{% block content %}
<script>
function playCard(card) {
let player = "{{player}}";
let c = card.toString();
var msg = {
type: "message",
fct: "playcard",
player: player,
card: c
};
let t = JSON.stringify(msg);
window.game_socket.send(t);
}
function setTrumpColor(color) {
let player = "{{player}}"
var msg = {
type: "message",
fct: "setTrumpColor",
player: player,
color: color
};
let t = JSON.stringify(msg);
window.game_socket.send(t);
}
</script>
<div style="font-family:Wizzta; font-size:100px"></div>
<div class="content">
<script src="/js-cardgame/pixi.min.js"></script>
<script src="/js-cardgame/js/card.js"></script>
<script src="/js-cardgame/js/carddeck.js"></script>
<script src="/js-cardgame/js/player.js"></script>
<script src="/js-cardgame/js/game.js"></script>
<script>
//let game = null;
//window.game = null;
//window.onload = function()
function setupGame(names, hand)
{
PIXI.AbstractRenderer.autoDensity = true;
let app = new PIXI.Application();
app.renderer.view.style.position = "absolute";
app.renderer.view.style.display = "block";
function resize()
{
let width = 1920;
let height = 1080;
let w = window.innerWidth;
let h = window.innerHeight;
let scale = Math.min(w/width, h/height)
app.stage.scale.x = scale;
app.stage.scale.y = scale;
app.renderer.resize(w, h);
}
function addResources(loader)
{
loader.add("mask", "/js-cardgame/deck/mask.png");
loader.add("back", "/js-cardgame/deck/back1.jpg");
for (let i = 0; i < 14; i++) {
["r", "g", "b", "y"].forEach(function (c) {
let name = c + ((i < 10) ? "0" + i : i);
loader.add(name, "/js-cardgame/deck/" + name + ".jpg");
});
}
for (let i = 1; i < 5; i++) {
loader.add("z" + i, "/js-cardgame/deck/z" + i + ".jpg");
loader.add("n" + i, "/js-cardgame/deck/n" + i + ".jpg");
}
}
resize();
window.addEventListener("resize", resize);
app.renderer.backgroundColor = 0x222222;
document.body.appendChild(app.view);
let loader = PIXI.Loader.shared;
addResources(loader);
loader.load(function(loader, resources)
{
game = new Game(app.stage, resources);
//game.init(['Hubert', 'Struppi', 'Patrice', 'Steffi', "Max", "Renate"]);
game.init(names)
game.give_round(hand)
//game.give_round(["z3", "b04", "r08", "g12", "y13", "r02", "b05", "b02", "b03", "g03", "g05"]);
//game.play_card(0, 0, "z3");
//game.play_card(1, 0, "y13");
//game.play_card(2, 0, "b02");
//game.play_card(3, 0, "r02");
//game.play_card(4, 0, "y05");
//game.play_card(5, 0, "g05");
//game.give_trick_to(0);
window.the_game = game;
});
};
</script>
</div>
<!-- <div class="content">
<h1><span class="font-semi-bold">Gambling Foo</span> <span class="smaller">A RESTful gaming service</span></h1>
<p class="lead">
Play a nice game of cards?<br>
<br>
<strong>Player {{player+1}} view</strong><br>
<strong> Table </strong><br>
{% for player,card in played_cards %}
||
{{player.name}}: {{card}}
{% endfor %}
||
<br>
<sub>
<strong>Tricks:</strong>
{% for player,_ in last_trick %}
||
{{player.name}}: {{player.tricks_taken}}
{% endfor %}
||
<br>
<strong>Last Trick:</strong>
{% for player,card in last_trick %}
||
{{player.name}}: {{card}}
{% endfor %}
||
</sub>
<br>
<strong> Your cards: </strong>
<ul>
<li>
<strong>Trump Card: {{trump_card}}</strong><br>
<strong>Trump Color: {{trump_color}}</strong><br>
</li>
{% for card in cards %}
<li>
<strong>>card {{loop.index}} is: {{card}} </strong><br>
{% if playerActive and not choose_trump_color %}
&lt;!&ndash;
<a href="/player/{{player}}/play/{{loop.index0}}">play card {{loop.index}}&lt;{{card}}&gt;</a>
<div style="background-color:#D94A38;width:170px;height:80px;margin:20px;padding-top:20px;color:#ffffff;font-weight:bold;font-size:18px;float:left;text-align:center;" onclick="playCard({{loop.index0}})">Play Me</div>
&ndash;&gt;
<button onclick="playCard({{loop.index0}})">Play {{card}}</button>
{% endif %}
</li>
{% endfor %}
{% if choose_trump_color and (player == choose_trump_player) %}
<strong>Choose Trump Color:</strong>
&lt;!&ndash;
<a href="/player/{{player}}/set_trump/r">Red&gt;</a>
<a href="/player/{{player}}/set_trump/g">Green&gt;</a>
<a href="/player/{{player}}/set_trump/b">Blue&gt;</a>
<a href="/player/{{player}}/set_trump/y">Yellow &gt;</a>
&ndash;&gt;
<button onclick="setTrumpColor('r')">Red</button>
<button onclick="setTrumpColor('g')">Green</button>
<button onclick="setTrumpColor('b')">Blue</button>
<button onclick="setTrumpColor('y')">Yellow</button>
{% endif %}
&lt;!&ndash;
<li>
<strong>Movie by IMDB code</strong><br>
<a href="/api/movie/tt0096754">GET /api/movie/{imdb_number}</a>
</li>
<li>
<strong>Top 10 Movies (by IMDB score)</strong><br>
<a href="/api/movie/top">GET /api/movie/top</a>
</li>
<li>
<strong>All genres</strong><br>
<a href="/api/movie/genre/all">GET /api/movie/genre/all</a>
</li>
<li>
<strong>Top movies for a given genres</strong><br>
<a href="/api/movie/genre/sci-fi">GET /api/movie/genre/{genre}</a>
</li>
&ndash;&gt;
</ul>
</p>
<p class="disclaimer">
Spam Bacon Sausage + Spam
Spam Spam Spam Spam Spam
Spam Baked Beans Spam
Spam Spam + Spam
</p>
</div>-->
{% endblock %}

View File

@ -2,26 +2,6 @@
{% block content %}
<script>
function setTrumpColor(color) {
let player = "{{player}}"
var msg = {
type: "message",
fct: "setTrumpColor",
player: player,
color: color
};
let t = JSON.stringify(msg);
window.game_socket.send(t);
}
function setupGame(player_names) {
}
</script>
<div class="content">
<h1><span class="font-semi-bold">Gambling Foo</span> <span class="smaller">A RESTful gaming service</span></h1>
<p class="lead">
@ -62,26 +42,16 @@
<li>
<strong>>card {{loop.index}} is: {{card}} </strong><br>
{% if playerActive and not choose_trump_color %}
<!--
<a href="/player/{{player}}/play/{{loop.index0}}">play card {{loop.index}}&lt;{{card}}&gt;</a>
<div style="background-color:#D94A38;width:170px;height:80px;margin:20px;padding-top:20px;color:#ffffff;font-weight:bold;font-size:18px;float:left;text-align:center;" onclick="playCard({{loop.index0}})">Play Me</div>
-->
<button onclick="playCard({{loop.index0}})">Play {{card}}</button>
{% endif %}
</li>
{% endfor %}
{% if choose_trump_color and (player == choose_trump_player) %}
<strong>Choose Trump Color:</strong>
<!--
<a href="/player/{{player}}/set_trump/r">Red&gt;</a>
<a href="/player/{{player}}/set_trump/g">Green&gt;</a>
<a href="/player/{{player}}/set_trump/b">Blue&gt;</a>
<a href="/player/{{player}}/set_trump/y">Yellow &gt;</a>
-->
<button onclick="setTrumpColor('r')">Red</button>
<button onclick="setTrumpColor('g')">Green</button>
<button onclick="setTrumpColor('b')">Blue</button>
<button onclick="setTrumpColor('y')">Yellow</button>
{% endif %}
<!--
<li>

View File

@ -7,7 +7,7 @@
<meta name="description" content="pyramid web application">
<meta name="author" content="Pylons Project">
<title>Free Online Gambling</title>
<title>Free Online Gamblingc</title>
<!-- Bootstrap core CSS -->
<link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
@ -22,113 +22,33 @@
<script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
<script>
window.the_game = null
// let socket = new WebSocket("wss://cowiz.struppi.name/ws");
if (window.location.hostname == '127.0.0.1') {
ws_schema = 'ws://';
}
else {
ws_schema = 'wss://';
}
let socket = new WebSocket(ws_schema+window.location.host+'/ws');
window.game_socket = socket
let socket = new WebSocket("wss://cowiz.struppi.name/ws");
socket.onopen = function(e) {
//alert("[open] Connection established");
//alert("Sending to server");
//socket.send("My name is John");
let player = "{{player}}"
var msg = {
//type: "message",
//fct: "requestInit",
type: "message",
fct: "getHand",
player: player,
};
let t = JSON.stringify(msg);
window.game_socket.send(t);
};
socket.onmessage = function(event) {
let msg = JSON.parse(event.data);
let fct = msg.fct;
if (fct == "reload") {
location.reload(true);
}
else if (fct == "getHand") {
window.hand = msg.cards;
let player = "{{player}}";
var msg_out = {
type: "message",
fct: "requestInit",
player: player,
};
let t = JSON.stringify(msg_out);
window.game_socket.send(t);
}
else if (fct == "startGame") {
let names = msg.names
setupGame(names, window.hand)
//alert('game is set up')
}
else if (fct == "cardPlayed") {
let player_id = msg.player;
let card_idx = msg.card_idx;
let card = msg.card;
let num_players = msg.num_players;
cardPlayed(player_id, card_idx, card, num_players)
}
else {
alert('unknown command: '+event.data);
}
//alert(`[message] Data received from server: ${event.data}`);
location.reload(true)
};
socket.onclose = function(event) {
if (event.wasClean) {
alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
//alert('closed clean');
//alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
//alert('closed unclean');
// e.g. server process killed or network down
// event.code is usually 1006 in this case
//alert('[close] Connection died');
}
};
socket.onerror = function(error) {
alert("[error]: "+error.message);
alert(`[error] ${error.message}`);
};
function playCard(card) {
let player = "{{player}}";
let c = card.toString();
var msg = {
type: "message",
fct: "playcard",
player: player,
card: c
};
let t = JSON.stringify(msg);
window.game_socket.send(t);
}
function cardPlayed(player, card_idx, card, num_players) {
let myself = "{{player}}";
let player_idx = ((player + num_players) - myself) % num_players;
window.the_game.play_card(player_idx, card_idx, card)
}
</script>
<style>
* {padding: 0; margin: 0}
@font-face {
font-family: "Wizzta";
src: url("/js-cardgame/font/wizzta-vada-webfont.woff2") format("woff2"),
url("/js-cardgame/font/wizzta-vada-webfont.woff") format("woff");
}
</style>
</head>
<body>
@ -168,7 +88,7 @@
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<!-- <script src="https://oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script> -->
<script src="/js-cardgame/jquery-3.5.1.min.js"></script>
<script src="https://oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script src="//oss.maxcdn.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/js/bootstrap.min.js"></script>
</body>
</html>

39
views/api_views.py Normal file
View File

@ -0,0 +1,39 @@
from responder import Response
from app_instance import api
response_count_max = 10
@api.route("/api/search/{keyword}")
def search_keyword(req, resp, keyword: str):
resp.media = {'keyword': keyword, 'hits': "movie_dicts", 'truncated_results': "limited"}
@api.route("/api/director/{director_name}")
def search_director(_, resp, director_name: str):
resp.media = {'keyword': director_name, 'hits': "movies_dicts", 'truncated_results': "limited"}
@api.route("/api/movie/genre/{genre}")
def movies_by_genre(_, resp: Response, genre: str):
resp.media = {'genre': genre, 'hits': "hits_dicts", 'truncated_results': "limited"}
@api.route("/api/movie/{imdb_number}")
def search_imdb(_, resp, imdb_number: str):
resp.media = {'foo': "bar"}
@api.route("/api/movie/top")
def top_movies(_, resp: Response):
resp.media = {'keyword': "keyword", 'hits': "hits_dicts", 'truncated_results': "limited"}
@api.route("/api/movie/genre/all")
def all_genres(_, resp: Response):
resp.media = {"all": "stuff"}
@api.route("/api/shuffle")
def cards_shuffle(_, resp: Response):
resp.media = {"shuffled": "done"}

View File

@ -5,15 +5,16 @@ from wiz_game import the_game
@api.route("/control/")
def index(req, resp):
round_finished = the_game.is_round_finished()
current_round = the_game.current_round
hand_finished = the_game.is_hand_finished()
trick_finished = the_game.is_trick_finished()
if round_finished:
if hand_finished:
trick_winner, highest_card = the_game.get_trick_winner()
winner = trick_winner.name
resp.content = api.template('home/control.html', deck=the_game.card_deck,
trump_card=the_game.trump_card, trump_color=the_game.get_trump_color(),
round_finished=True, trick_finished=False, trick_winner=winner,
hand_finished=True, trick_finished=False, trick_winner=winner,
highest_card=highest_card
)
elif trick_finished:
@ -30,40 +31,28 @@ def index(req, resp):
round_finished=False, trick_finished=False
)
@api.route("/control/next_round/")
async def start_next_round(req, resp):
the_game.next_round()
await the_game.send_page_reload()
@api.route("/control/next_hand/")
async def start_next_hand(req, resp):
the_game.next_hand()
for ws in the_game.websockets:
try:
await ws.send_text("reload")
except Exception as e:
print("ws: got {}".format(e))
api.redirect(resp, '/control/', status_code=303)
@api.route("/control/next_trick/")
async def start_next_trick(req, resp):
the_game.next_trick()
await the_game.send_page_reload()
api.redirect(resp, '/control/', status_code=303)
@api.route("/control/undo_last/")
async def undo_last(req, resp):
round_finished = the_game.is_round_finished()
if the_game.played_cards:
if not round_finished:
p, c = the_game.played_cards.pop()
the_game.active_player -= 1
p.add_card(c)
await the_game.send_page_reload()
else:
if the_game.num_tricks_played > 0:
the_game.num_tricks_played -= 1;
the_game.played_cards = the_game.last_trick;
the_game.active_player = len(the_game.players) - 1
player, _ = the_game.get_trick_winner()
player.tricks_taken -= 1
the_game.players_ordered = [p for p, _ in the_game.played_cards]
p, c = the_game.played_cards.pop()
p.add_card(c)
await the_game.send_page_reload()
for ws in the_game.websockets:
try:
await ws.send_text("reload")
except Exception as e:
print("ws: got {}".format(e))
api.redirect(resp, '/control/', status_code=303)
#@api.route("/control/deal/{cards}")
#def deal(req, resp, cards):
# the_game.deal_cards(int(cards))
# api.redirect(resp, '/control/', status_code=303)

View File

@ -1,29 +0,0 @@
from app_instance import api
from wiz_game import the_game
from starlette.websockets import WebSocketDisconnect
import asyncio
# don't define here, it's defined elsewhere!
#playing_lock = asyncio.Lock()
@api.route("/gplayer/{player}")
def show(req, resp, player: str):
p = int(player)
tcard = the_game.trump_card
tcolor = the_game.get_trump_color()
try:
isActive = the_game.players_ordered[the_game.active_player].id == p
except IndexError:
isActive = False
prev_player = the_game.get_prev_player()
if tcard and tcard.value == 'Z' and tcolor == '-':
choose_trump_color = True
else:
choose_trump_color = False
resp.content = api.template('home/gplayer.html', player=p, playerActive=isActive, choose_trump_player=prev_player,
cards=the_game.players[p].cards, choose_trump_color=choose_trump_color,
trump_card=tcard, trump_color=tcolor, played_cards=the_game.played_cards, last_trick=the_game.last_trick)

View File

@ -1,56 +0,0 @@
import os
from app_instance import api
@api.route("/js-cardgame/{file}")
def css(req, resp, file):
resp.headers['Content-Type'] = 'application/javascript'
full_file = os.path.join(
os.path.dirname(__file__),
'..',
'js-cardgame',
file
)
with open(full_file, encoding='utf-8') as fin:
resp.content = fin.read()
@api.route("/js-cardgame/deck/{file}")
def css(req, resp, file):
resp.headers['Content-Type'] = 'image/jpeg'
full_file = os.path.join(
os.path.dirname(__file__),
'..',
'deck/',
file
)
with open(full_file, 'rb') as fin:
resp.content = fin.read()
@api.route("/js-cardgame/font/{file}")
def css(req, resp, file):
resp.headers['Content-Type'] = 'application/octet-stream'
full_file = os.path.join(
os.path.dirname(__file__),
'..',
'js-cardgame',
file
)
with open(full_file, 'rb') as fin:
resp.content = fin.read()
@api.route("/js-cardgame/js/{file}")
def css(req, resp, file):
resp.headers['Content-Type'] = 'application/javascript'
full_file = os.path.join(
os.path.dirname(__file__),
'..',
'js-cardgame',
'js',
file
)
with open(full_file, encoding='utf-8') as fin:
resp.content = fin.read()

View File

@ -3,22 +3,22 @@ from app_instance import api
from wiz_game import the_game
from starlette.websockets import WebSocketDisconnect
import asyncio
import json
playing_lock = asyncio.Lock()
@api.route("/player/{player}")
def show(req, resp, player: str):
p = int(player)
name = the_game.players[p].name
tcard = the_game.trump_card
tcolor = the_game.get_trump_color()
#isActive = the_game.is_players_turn(p)
try:
isActive = the_game.players_ordered[the_game.active_player].id == p
print("show p: {} | {}".format(the_game.players_ordered[the_game.active_player].id, p))
except IndexError:
isActive = False
print("show p: {} | {}".format('None', p))
#active_player = the_game.active_player
prev_player = the_game.get_prev_player()
if tcard and tcard.value == 'Z' and tcolor == '-':
choose_trump_color = True
@ -29,125 +29,58 @@ def show(req, resp, player: str):
trump_card=tcard, trump_color=tcolor, played_cards=the_game.played_cards, last_trick=the_game.last_trick)
async def play_card(player, card):
global playing_lock
async with playing_lock:
try:
isActive = the_game.players_ordered[the_game.active_player].id == player
except IndexError:
isActive = False
if isActive:
the_game.play_card(player, card)
if the_game.is_round_finished():
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
elif the_game.is_trick_finished():
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
the_game.next_trick()
await the_game.send_page_reload()
async def play_card_js(player_id, card_idx):
global playing_lock
async with playing_lock:
try:
isActive = the_game.players_ordered[the_game.active_player].id == player_id
except IndexError:
isActive = False
if isActive:
card = the_game.play_card(player_id, card_idx)
if the_game.is_round_finished():
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
elif the_game.is_trick_finished():
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
the_game.next_trick()
s = card.json_serialise()
msg = {"type": "message", "fct": "cardPlayed", "card": s, "card_idx": card_idx,
"player": player_id, "num_players": len(the_game.players)}
for ws in the_game.websockets:
try:
await ws.send_json(msg)
except Exception:
the_game.websockets.remove(ws)
@api.route("/player/{player}/play/{card}")
async def play(req, resp, player: str, card: str):
lock = asyncio.Lock()
p = int(player)
c = int(card)
play_card(p, c)
async with lock:
try:
isActive = the_game.players_ordered[the_game.active_player].id == p
except IndexError:
isActive = False
print("show p: {} | {}".format('None', p))
if isActive:
the_game.play_card(p, c)
if the_game.is_hand_finished():
print("hand finished")
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
#the_game.next_hand()
elif the_game.is_trick_finished():
print("trick finished")
trick_winner, highest_card = the_game.get_trick_winner()
trick_winner.take_trick()
the_game.next_trick()
url = '/player/'+player
for ws in the_game.websockets:
try:
await ws.send_text("reload")
except Exception as e:
print("ws: got {}".format(e))
api.redirect(resp, url, status_code=303)
@api.route("/player/{player}/set_trump/{trump}")
async def set_trump_color_rest(req, resp, player, trump):
async def set_trump_color(req, resp, player, trump):
p = int(player)
the_game.set_trump_color(trump)
url = '/player/'+player
await the_game.send_page_reload()
api.redirect(resp, url, status_code=303)
async def set_trump_color(player, color):
p = int(player)
if p == the_game.players_ordered[-1].id:
the_game.set_trump_color(color)
await the_game.send_page_reload()
async def initGame(player, ws):
p = int(player)
players = the_game.players[p:] + the_game.players[:p]
n = [x.name for x in players]
msg = {"type": "message", "fct": "startGame", "names": n}
await ws.send_json(msg)
async def getHand(player, ws):
p = int(player)
c = the_game.players[p].cards
s = [x.json_serialise() for x in c]
msg = {"type": "message", "fct": "getHand", "cards": s}
await ws.send_json(msg)
async def ws_handler(ws):
await ws.accept()
the_game.websockets.append(ws)
while True:
for ws in the_game.websockets:
try:
x = await ws.receive_json()
fct = x['fct']
if fct == 'playcard':
p = int(x['player'])
c = int(x['card'])
await play_card_js(p, c)
elif fct == 'setTrumpColor':
player = x['player']
color = x['color']
await set_trump_color(player, color)
elif fct == "requestInit":
player = x['player']
await initGame(player, ws);
elif fct == "getHand":
player = x['player']
await getHand(player, ws)
else:
print("confused :(")
except WebSocketDisconnect:
the_game.websockets.remove(ws)
break;
await ws.send_text("reload")
except Exception as e:
print("ws: got {}".format(e))
api.redirect(resp, url, status_code=303)
@api.route('/ws', websocket=True)
async def websocket(ws):
task = asyncio.create_task(ws_handler(ws))
the_game.ws_tasks.append(task)
await task;
await ws.accept()
the_game.websockets.append(ws)
try:
foo = await ws.receive_text()
except WebSocketDisconnect:
the_game.websockets.remove(ws)

View File

@ -1,7 +1,7 @@
import random
from operator import attrgetter
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
@ -9,10 +9,9 @@ def chunks(lst, n):
class Card:
def __init__(self, color, value, idx=None):
def __init__(self, color, value):
self.color = color
self.value = value
self.idx = idx
def __str__(self):
sc = self.color if self.color else ' '
@ -22,13 +21,6 @@ class Card:
def __repr__(self):
return str(self)
def json_serialise(self):
if self.color and self.color != '-':
s = "{}{:02d}".format(self.color, self.value)
else:
s = "{}{}".format(self.value.lower(), self.idx)
return s
def get_higher_card(card1: Card, card2: Card, trump_color: str):
"""
@ -36,7 +28,7 @@ def get_higher_card(card1: Card, card2: Card, trump_color: str):
returns: True if card2 beats card1, otherwise False
"""
if card2.value == 'N':
# no way to win if 'N' comes in second
# no way to win in 'N' comes in second
return False
elif card1.value == 'Z':
# no way to win if 'Z' was already played
@ -80,10 +72,6 @@ class Player:
def take_trick(self):
self.tricks_taken += 1
def add_card(self, card):
self.cards.append(card)
self.cards = sorted(self.cards, key=attrgetter('color', 'value'))
class WizGame:
def __init__(self, player_names: list):
@ -100,7 +88,6 @@ class WizGame:
self.players_ordered = self.players
self.last_trick = None
self.websockets = []
self.ws_tasks = []
def start_game(self):
self.create_deck()
@ -118,10 +105,10 @@ class WizGame:
for color in ["b", "r", "g", "y"]:
for val in range(1, 14):
self.card_deck.append(Card(color, val))
for idx in range(1, 5):
self.card_deck.append(Card('-', 'Z', idx))
for idx in range(1, 5):
self.card_deck.append(Card('-', 'N', idx))
for _ in range(1, 5):
self.card_deck.append(Card('-', 'Z'))
for _ in range(1, 5):
self.card_deck.append(Card('-', 'N'))
def get_trump_color(self):
card = self.trump_card
@ -163,16 +150,16 @@ class WizGame:
else:
return True
def is_round_finished(self):
def is_hand_finished(self):
h = self.is_trick_finished()
if h and self.num_tricks_played == self.current_round:
return True
else:
return False
def next_round(self):
max_rounds = len(self.card_deck)/len(self.players)
if self.current_round <= max_rounds:
def next_hand(self):
max_hands = len(self.card_deck)/len(self.players)
if self.current_round <= max_hands:
self.current_round += 1
self.start_player += 1
if self.start_player >= len(self.players):
@ -203,7 +190,6 @@ class WizGame:
self.active_player += 1
if self.is_trick_finished():
self.num_tricks_played += 1
return c # return card to calling function
def set_trump_color(self, trump_color):
if self.trump_card.value != 'Z':
@ -213,6 +199,7 @@ class WizGame:
return False
else:
self.trump_card = Card(trump_color, 'Z')
#self.trump_card.color = trump_color
return True
def get_prev_player(self):
@ -221,15 +208,7 @@ class WizGame:
else:
return self.start_player-1
async def send_page_reload(self):
for ws in self.websockets:
try:
msg = {"type": "message", "fct": "reload"};
await ws.send_json(msg)
except Exception as e:
pass
p = ["spam", "egg", "ham", "tomato"]
p = ["A", "B", "C", "D", "E"]
the_game = WizGame(p)