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を削除する

次回予定

プレイヤーが一人かけた時点で勝敗情報が変化してしまうのでその対策予定


この記事が気に入ったらサポートをしてみませんか?