今日はジャンケンフレームワークを書いてみました。
ジャンケンコードは昨年より、書いては捨ててを幾度か繰り返してたのですが
ようやく部品として取り扱えそうなものが出来ました。
今まで書いてきたものは1対1専用の一人称構造でしたが
今度のは複数人対戦を可能とした三人称構造としました。
・手がバラけた場合をあいこ判定とする
・勝ち負けが各プレイヤーにより異なる
という辺りで汚いコードを書いてしまってるかも知れません。
参考にしたソースも無いので、もっと綺麗な判定方法があるのかもです。
サンプルコードを含むプロジェクト一式、ライブラリ・フレームワーク一式は
下記サイトからダウンロードできます。
Nitro Developer Style
http://page.freett.com/ntr/
ソース
main.c
/*--------------------------------------------------------------------------------- Janken framework test version 0.01 Jun 01, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <nds.h> #include "fwmy/Janken.h" #define PLAYER_MAX 3 const char *str_hand[] = {"GOO", "CHOKI", "PAR"}; const char *str_judge[] = {"MAKE", "AIKO", "KACHI"}; void drawJudge(Janken janken, int player_num); //--------------------------------------------------------------------------------- int main(void){ //--------------------------------------------------------------------------------- consoleDemoInit(); printf("Janken framework test\n\nversion 0.01\nJun 01, 2010\n\nBy REGEKATSU\n\n\n"); printf("usage:\nKEY_A: SetHand (random)\nKEY_B: Clear\nKEY_ST:Judge\nKEY_SL:Destroy & exit"); srand(time(NULL)); Janken janken = Janken_Create(PLAYER_MAX); drawJudge(janken, PLAYER_MAX); while(1){ swiWaitForVBlank(); scanKeys(); if(keysDown() & KEY_A){ int i; for(i = 0;i < PLAYER_MAX;i++){ Janken_SetHand(janken, i, rand() % HAND_MAX); } } if(keysDown() & KEY_B){ Janken_Clear(janken); drawJudge(janken, PLAYER_MAX); } if(keysDown() & KEY_START){ Janken_Judge(janken); drawJudge(janken, PLAYER_MAX); } if(keysDown() & KEY_SELECT){ Janken_Destroy(janken); return 0; } } } //--------------------------------------------------------------------------------- void drawJudge(Janken janken, int player_num){ //--------------------------------------------------------------------------------- if(janken == NULL) return; int i; for(i = 0;i < player_num;i++){ printf("\x01b[%d;0H\x01b[2Kplayer=%02d,hand=%s,judge=%s", 15 + i, i, str_hand[Janken_GetHand(janken, i)], str_judge[Janken_GetJudge(janken, i)]); } } //---------------------------------------------------------------------------------
Janken.h
/*--------------------------------------------------------------------------------- janken framework header version 0.01 Jun 01, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #ifndef _JANKEN_H_ #define _JANKEN_H_ typedef struct _Janken *Janken; typedef enum{ JUDGE_MAKE = 0, JUDGE_AIKO, JUDGE_KACHI }JUDGE_JANKEN; typedef enum{ HAND_GOO = 0, HAND_CHOKI, HAND_PAR, HAND_MAX }HAND_JANKEN; #ifdef __cplusplus extern "C" { #endif //ジャンケンの場を生成します。引数には参加プレイヤー数を指定します。 Janken Janken_Create(int player_num); //ジャンケンの場を破棄します。 Janken Janken_Destroy(Janken janken); //全プレイヤーの設定情報(ジャンケンの手、勝敗)をクリア(初期化)します。 void Janken_Clear(Janken janken); //現在設定されてる、プレイヤーのジャンケンの手で勝敗を判定します。 void Janken_Judge(Janken janken); //プレイヤーの、ジャンケンの手を設定します。 void Janken_SetHand(Janken janken, int player_no, int player_hand); //プレイヤーの、現在のジャンケンの手を取得します。 int Janken_GetHand(Janken janken, int player_no); //プレイヤーの、現在の勝敗を取得します。 int Janken_GetJudge(Janken janken, int player_no); #ifdef __cplusplus } #endif #endif //_JANKEN_H_
Janken.c
/*--------------------------------------------------------------------------------- janken framework routine version 0.01 Jun 01, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #include <stdlib.h> #include <string.h> #include "Janken.h" typedef struct{ int hand; int judge; }Player; typedef struct _Janken{ int player_num; Player *player; }_Janken; int janken_JudgeHand(int hand1, int hand2); //--------------------------------------------------------------------------------- Janken Janken_Create(int player_num){ //--------------------------------------------------------------------------------- Janken janken; janken =(Janken)malloc(sizeof(_Janken)); janken->player_num = (player_num <= 1) ? 2 : player_num; janken->player = malloc(sizeof(Player) * janken->player_num); Janken_Clear(janken); return janken; } //--------------------------------------------------------------------------------- Janken Janken_Destroy(Janken janken){ //--------------------------------------------------------------------------------- if(janken == NULL) return NULL; free(janken->player); free(janken); return NULL; } //--------------------------------------------------------------------------------- void Janken_Clear(Janken janken){ //--------------------------------------------------------------------------------- if(janken == NULL) return; memset(&janken->player, 0, sizeof(Player) * janken->player_num); } //--------------------------------------------------------------------------------- void Janken_Judge(Janken janken){ //--------------------------------------------------------------------------------- if(janken == NULL) return; int i, j, kind_hand[HAND_MAX], kind_sum, ather_hand = 0; memset(kind_hand, 0, sizeof(kind_hand)); //全プレイヤーの出した手の種類を得る。 for(i = 0;i < janken->player_num;i++){ kind_hand[janken->player[i].hand] = 1; } //出された手の種類数を得る。 kind_sum = 0; for(i = 0;i < HAND_MAX;i++){ kind_sum += kind_hand[i]; } //出された全ての手が1種のみ、または3種全てあった場合、「あいこ」とする。 if(kind_sum != 2){ for(i = 0;i < janken->player_num;i++){ janken->player[i].judge = JUDGE_AIKO; } //2種の場合、強い手を「勝ち」とし、弱い手を「負け」とする。 }else{ for(i = 0;i < janken->player_num;i++){ for(j = 0;j < HAND_MAX;j++){ if(kind_hand[j] != 0 && janken->player[i].hand != j){ ather_hand = j; } } janken->player[i].judge = janken_JudgeHand(janken->player[i].hand, ather_hand); } } } //--------------------------------------------------------------------------------- void Janken_SetHand(Janken janken, int player_no, int player_hand){ //--------------------------------------------------------------------------------- if(janken == NULL) return; if(player_no < 0 || player_no >= janken->player_num) return; if(player_hand < HAND_GOO || player_hand >= HAND_MAX) return; janken->player[player_no].hand = player_hand; } //--------------------------------------------------------------------------------- int Janken_GetHand(Janken janken, int player_no){ //--------------------------------------------------------------------------------- if(janken == NULL) return -1; if(player_no < 0 || player_no >= janken->player_num) return -1; return janken->player[player_no].hand; } //--------------------------------------------------------------------------------- int Janken_GetJudge(Janken janken, int player_no){ //--------------------------------------------------------------------------------- if(janken == NULL) return -1; if(player_no < 0 || player_no >= janken->player_num) return -1; return janken->player[player_no].judge; } //--------------------------------------------------------------------------------- int janken_JudgeHand(int hand1, int hand2){ //--------------------------------------------------------------------------------- int judge; if(hand1 == hand2){ judge = JUDGE_AIKO; }else if((hand1 + 1) % 3 == hand2){ judge = JUDGE_KACHI; }else{ judge = JUDGE_MAKE; } return judge; } //---------------------------------------------------------------------------------