Djangoでブラックジャックを目指す 23 前回の確認と終了処理
今回やること
前回勝利者判定時の確認に使用したviewを説明
ゲームを終了し部屋を閉じる処理
前回までやったこと
Djangoのプロジェクトを作る
start appでacounts ,game の2つのappのひな型を作成
accounts (app)にログイン用のCustomUserのモデルを作成
settings.pyを編集ログインユーザーを作成したCustomUserに変更
game に(app)にモデルをセットする
game (app)にforms.py(という空のファイル)を作成
formをセットする
allatuthを使ってログイン周りのアカウント部分を作成
ゲーム画面までのルーティング
表示用のベーステンプレートの複製
テンプレートとViewを連携させる
エントランスページ最低限の機能を考える
部屋作成機能 の実装
entrance → gameroom へのルーティング
カードの一覧作成処理
カードの一覧のIDを取得
カードリストをシャッフル→DB格納
初期デッキ生成処理の組み込み
ゲームボタンの生成
ゲーム準備完了ボタンの処理
全員参加意思が行われた時のターン進行処理
エントランス表示処理の変更
元の部屋に帰るメゾット追加
元の部屋の戻る処理の確認
2ターン目の流れの確認
カードをドローする処理の動作確認
フェイズを進行させる
手札の表示
点数処理
役の確認チェック
プレイヤーの行動処理
ルームに内のプレイヤー全員の手札を表示
全プレイヤーに得点情報の追加
勝利者判定
前回の結果確認用コード
<appFolder>/views.py
def gameRoom(request,room_id):
template_name = 'game/gameroom.html'
context={'msg' : 'gama Room NO'+ str(room_id)}
room = GameRooms.objects.get(pk=room_id)
context.update({'turn':room.phase_counter})
player = get_player(request.user)
roomplayer= get_roomPlayer(player, room)
if roomplayer is None:
return redirect(reverse_lazy('game:entrance'))
#ルーム作成者かプレイヤーのみの処理
if roomplayer.player_job == 5 or roomplayer.player_job == 7:
--------------------略--------------------------------
if room.phase_counter == 4:
context.update({'turn':room.phase_counter})
if request.method == 'GET':
#手札を取得する
hand_card = get_player_hand(room,roomplayer)
#コンテキストに追加する
context.update({'playerhand':hand_card})
#ルーム内プレイヤーの手札情報の取得
all_player_hands= room_all_player_card(room)
#その手札情報に役と点数情報を付与
all_player_handinfo=all_player_pointset(all_player_hands)
#勝利者情報を付与
all_player_handinfo=get_win_player(all_player_handinfo)
#自分が勝利者か判定
you_win= is_user_win(request.user, all_player_handinfo)
#コンテキストに追加する
context.update({'roomplayerhand':all_player_handinfo})
context.update({'you_win':you_win})
<appFolder>/template/<appname>/gameroom.html
{% extends 'base.html' %}
{% block content %}
<h1>Game Room</h1>
{{msg}}
<p>{{turn}}ターン目</p>
<p>合計</p>{{card_point}}
{% if turn == 4 %}
<h1>{{you_win}}</h1>
{% endif %}
{% for card in playerhand %}
<ul>
{{card.as_ul}}
</ul>
{% endfor %}
{% for room_user_info in roomplayerhand %}
<p>{{room_user_info.user_name}}:{{room_user_info.point}}:{{room_user_info.win}}</p>
{% for card in room_user_info.hand %}
{{card.as_p}}
{% endfor %}
{% endfor %}
流れと解説
views.py
略までは共通処理
4ターン目(結果フェイズ)の時の限定処理として
手札を取得する
hand_card = get_player_hand(room,roomplayer)
ルーム内プレイヤーの手札と役と点数情報を取得
all_player_hands= room_all_player_card(room)
all_player_handinfo=all_player_pointset(all_player_hands)
↑に勝利者情報を付与(前回作成したメゾット)
all_player_handinfo=get_win_player(all_player_handinfo)
自分が勝利者か判定し取得(前回作成したメゾット)
you_win= is_user_win(request.user, all_player_handinfo)
を取得しcontextに格納→htmlへ送信する
一方受け取ったHTML側では
gameroom.html
{% if turn == 4 %}~{% endif %}
で4ターン目の時のみ表示させる情報を選別し
{{you_win}} によって自分が勝ったが負けたかを表示させる
残りの部分は
{% for room_user_info in roomplayerhand %}
<p>{{room_user_info.user_name}}:{{room_user_info.point}}:{{room_user_info.win}}</p>
{% for card in room_user_info.hand %}
{{card.as_p}}
{% endfor %}
{% endfor %}
for内でルームプレイヤーのリストから単体を取り出し手札以外の情報を
<p>{{room_user_info.user_name}}:{{room_user_info.point}}:{{room_user_info.win}}</p>
としてまとめて表示
手札はさらにfor文を用いて手札リストからカードを1枚ずつ取得して並べる
これでちゃんと望み通りの結果になっているかを確認できる
ゲーム終了操作
ゲームが終了後の流れを確認
確認ボタンを表示
ボタンをを押したらエントランスに飛ばす
と同時にroomplayerから対象を削除
すべてのプレイヤーがいなくなったら
ルームを削除
ルームのカード情報も削除
完成コード
views.py 追加部分
def gameRoom(request,room_id):
--------------------略--------------------------------
if room.phase_counter == 4:
--------------------略--------------------------------
if request.method == 'POST':
#ルームプレイヤーの削除
roomplayer.delete();
if RoomPlayers.objects.filter(room_id= room).count()==0:
CardAreas.objects.filter(room_id= room).delete()
room.delete()
return redirect(reverse_lazy('game:entrance'))
entrance.html 追加部分
{% if turn == 4 %}
<h1>{{you_win}}</h1>
<form class="" method="post">
{% csrf_token %}
<input type =submit name = "exit" value ="確認して退出" >
</form>
{% endif %}
確認ボタンを表示
entrance.html
ターン数に関してはDBからなのでHTMLからの送信の必要はない
今回必要なのはpost送信されたということなので
<form class="" method="post">でくくったsubmitで送信を行うだけ
ボタンをを押したらエントランスに飛ばす
と同時にroomplayerから対象を削除
views.py
if request.method == 'POST':
roomplayer.delete();
return redirect(reverse_lazy('game:entrance'))
これがプレイヤー全員に対するボタンを押したときの共通処理
roomplayerはターンに関係なく取得しているroomplayerによってquerysetとして取得しているので.deleteをやるだけで削除される
すべてのプレイヤーがいなくなったら
ルームを削除
ルームのカード情報も削除
RoomPlayers.objects.filter(room_id= room).count()==0:
現在のルームのプレイヤーの数をカウントすることでプレイヤーの有無を判定
CardAreas.objects.filter(room_id= room).delete()
room.delete()
CardAreas.objects.filterはroomを外部キーとして使えるのでそれをもって削除
そのあとでroomを削除する
次回予定
プレイヤーが一人かけた時点で勝敗情報が変化してしまうのでその対策予定
この記事が気に入ったらサポートをしてみませんか?