見出し画像

Django でブラックジャックを目指す 16

今回やること

カードをドローする処理の動作確認
フェイズを進行させる


前回までやったこと

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ターン目の流れの確認

前回のバグを修正

# カードを移動させる処理
def send_card(room ,send_area,get_area,send_player=None,get_player=None ):
   area=None


   #移動先情報を格納 元の場所にカードがある前提
   if send_player is None:
       area= CardAreas.objects.filter(room_id=room,area = send_area).order_by('id').first()
   else:
       area= CardAreas.objects.filter(room_id=room,area = send_area,room_player_id=send_player).order_by('id').first()

   #移動先の情報に更新してUpdate
   if area is not None:
       area.area=get_area
       area.room_player_id=get_player
       area.save()


order_by  に''の付け忘れのためidという変数で並べようとしてしまうのでエラーが発生してしまった。

f send_player is None:
誤りはif send_player in not None
送り手情報がないときに送りて情報を入れようとしている
エラーは出ないですが意図してる状況と真逆なので修正

ドロー処理の確認のためのgame viewを(一時的に)修正します

<appFolder>/views.py(抜粋)

画像3



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 room.phase_counter == 2:
           draw_card(room,roomplayer)#ドロー動作確認用



   return render(request ,template_name ,context)
   
   

現時点のではフェイズは2まで進行しているので
上記room.phase_counter == 2:を条件としているが
別の部屋を作って効果を確認する場合はcounter条件を1にするなど変更を行う

確認開始

viewにアクセスを行う

画像2

その後更新を1回行う

画像3

areaが1→2(山札→手札)と変わりroomplayeridが1となって所有者が設定されたことを確認する

初期手札の分配処理の流れ

ルームプレイヤー全員を取得
プレイヤー一人一人でループ
ループ内で手札の枚数を確認
指定枚数未満ならカードを引く処理を行う
規定枚数になったら次のプレイヤーへ

完成コード
<appFolder>/views.py

画像4

# 全員の手札が指定した数になるまで山札からカードを分配する
def distribute_card(room,num):

   players = RoomPlayers.objects.filter(room_id = room)
   for player in players:
       player_hand =  CardAreas.objects.filter(room_id = room , room_player_id = player).count()

       #指定の真伊豆宇になるまでカードを手札に加える
       if num > player_hand:
           for n in range(num-player_hand):
               draw_card(room,player);

#初期手札の分配
def first_card_distribute(room):
   #初期手札は2枚
   distribute_card(room,2);

中身の照らし合わせ

ルームプレイヤー全員を取得
players = RoomPlayers.objects.filter(room_id = room)

参加ルームでRoomplayerを指定すればOK
指定ルームのすべてのプレイヤーの情報を取得


プレイヤー一人一人でループ
for player in players:
これにより先ほど取得したプレイヤーにてforEachのループ処理が行われる


ループ内で手札の枚数を確認
CardAreas.objects.filter(room_id = room , room_player_id = player).count()
ループ情報からルームプレイヤー情報は取得できているのでfilterで条件を絞って全取得
そのうえでcountすることでプレイヤーの手持ちカードを確認することができる


指定枚数未満ならカードを引く処理を行う
規定枚数になったら次のプレイヤーへ

if num > player_hand:
for n in range(num-player_hand):

まず最初から規定枚数以上だと処理でエラーが出る可能性が高いので
最初から規定枚数とプレイヤーのカード枚数を比較しておく
そのうえで規定枚数になるまでループ処理を行うfor文を付与

今回はBJなので初期手札は2枚これを固定で処理するためのメゾットとして
first_card_distribute(room):を作り簡略化した状態で外から呼び出す


確認開始

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 room.phase_counter == 2:
            #draw_card(room,roomplayer)#ドロー動作確認用
           first_card_distribute(room)


   return render(request ,template_name ,context)
   

さっきの確認処理のドローをコメントアウト
今回の初期分配用のメゾットを追加する

これを実装後先補とのようにGameroomにアクセスを行うと

画像5

のようにカードが2枚ずつ分配されていることを確認


フェイズを進行させる

上記の処理によりすべてのプレイヤーの操作に関係なく次のフェイズに移れるのて
フェイスカウンターを3にする処理を追加する

#単にフェイズ(ターン)カウンターを1加算するもしくは指定の値に変える処理
def phase_counter_plus_or_set(room,set_num=None):
   if set_num is None:
       room.phase_counter = room.phase_counter +1
   else:
       room.phase_counter = set_num
   room.save()



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 room.phase_counter == 2:
            first_card_distribute(room)#初期手札の分配
           phase_counter_plus_or_set(room,3)#フェイズカウンターを+して進行

           return redirect(reverse_lazy('game:gameroom' ,kwargs={'room_id':room_id}))


   return render(request ,template_name ,context)

phase_counter_plus_or_set(room,set_num=None):
roomを受け取ってそのphase_counterを加算もしくは指定の値に変更する

これを初期分配処理のあとに追加する(途中でエラーが出たときは止まるのでカウンターは加算されない)
最後に今のページにリダイレクトしてカウントが3に変更されているのを確認できるようにする

確認

画像6

アクセスした時点でターンカウントが3へ変わっている

画像7

データベースも指定枚数を分配してあるので新しく増えるようなことは発生しないことを確認

次回予定

自分の手札の表示処理を予定

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