俺々フレームワーク。カードデッキ&トランプ。
先日のトランプフレームワークをカードデッキフレームワークとして独立することで、
基本的なカードデッキの動作を提供。
カードデッキフレームワークをベースにトランプとしてパックすることで
トランプデッキ動作を提供する。
といった作りになってます。
データ構造にトランプならではの項目が増えることもなかったので
継承を実装するまでもなく、パック関数化するだけで済みました。
インスタンス生成が Deck でなく Trump となってて
あたかも独自のデータ構造かと思わせてますが typedef で単純に Deck 構造体ポインタの型名を増やしただけです。
Trump のみの利用者には Trump のみ見せるというのを提供するが為の記述です。
typedef struct _Deck *Trump;
Deck framework, and
Trump framework test
サンプル一式またはライブラリ&フレームワーク一式は以下のサイトよりダウンロードできます。
http://page.freett.com/ntr/
ソース(フレームワーク部、テストプログラム部のみ)。
main.c
/*--------------------------------------------------------------------------------- Deck framework, and Trump framework test version 0.01 May 16, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #include <stdio.h> #include <nds.h> #include "libmy/Random.h" #include "fwmy/Trump.h" #define SHUFFLE_NUM 100 const char suit[] = { 0x05, //club 0x04, //diamond 0x03, //heart 0x06 //spade }; const char *rank[] = {"A ", "2 ", "3 ", "4 ", "5 ", "6 ", "7 ", "8 ", "9 ", "10", "J ", "Q ", "K "}; int card_num[TRUMP_MAX + 1], card_index; PrintConsole top_cons, bottom_cons; void clearValue(void); void drawDeck(Trump trump); //--------------------------------------------------------------------------------- int main(void) { //--------------------------------------------------------------------------------- //initVideoMode videoSetMode(MODE_0_2D); videoSetModeSub(MODE_0_2D); //initVRAMBank vramSetBankA(VRAM_A_MAIN_BG); vramSetBankC(VRAM_C_SUB_BG); //initConsole top_cons = *consoleInit(0, 0, BgType_Text4bpp, BgSize_T_256x256, 0, 1, true, true); bottom_cons = *consoleInit(0, 0, BgType_Text4bpp, BgSize_T_256x256, 0, 1, false, true); //initKeysDownRepeat u32 kdr; keysSetRepeat(6, 3); consoleSelect(&bottom_cons); printf("Deck framework, and\n Trump framework test\n\nversion 0.01\nMay 16, 2010\n\nBy REGEKATSU\n\n\n"); consoleSelect(&top_cons); printf("\x01b[18;0Husage:\n" "KEY_A: GetCard, KEY_B: SetCard\n" "KEY_Y: ReqCard, KEY_X: ShfDeck\n" "KEY_ST:ClrDeck, KEY_SL:DstDeck\n" ); //CreateDeck Trump trump = Trump_Create(); Random random = Random_Create(GENERATOR_LCGS); clearValue(); while(1){ swiWaitForVBlank(); scanKeys(); kdr = keysDownRepeat(); //GetCardNumber, GetCardUse & drawDeck drawDeck(trump); //GetCard if(kdr & KEY_A){ if(card_index < TRUMP_MAX){ card_num[card_index] = Trump_GetCard(trump); consoleSelect(&bottom_cons); printf("GetCard %c%s\n", suit[ SET_SUIT(card_num[card_index])], rank[SET_RANK(card_num[card_index])]); card_index++; } //SetCard }else if(kdr & KEY_B){ if(card_index > 0){ card_index--; Trump_SetCard(trump, card_num[card_index]); consoleSelect(&bottom_cons); printf("SetCard %c%s\n", suit[ SET_SUIT(card_num[card_index])], rank[SET_RANK(card_num[card_index])]); card_num[card_index] = -1; } //RequestCard }else if(kdr & KEY_Y){ if(card_index < TRUMP_MAX){ card_num[card_index] = Trump_RequestCard(trump, Random_GetValue(random) % TRUMP_MAX); if(card_num[card_index] != -1){ consoleSelect(&bottom_cons); printf("RequestCard %c%s\n", suit[ SET_SUIT(card_num[card_index])], rank[SET_RANK(card_num[card_index])]); card_index++; } } //ShuffleDeck }else if(kdr & KEY_X){ Trump_Shuffle(trump, Random_GetValue(random), SHUFFLE_NUM); consoleSelect(&bottom_cons); printf("ShuffleDeck %d\n", SHUFFLE_NUM); } //ClearDeck if(kdr & KEY_START){ Trump_Clear(trump); clearValue(); consoleSelect(&bottom_cons); printf("ClearDeck\n"); //DestroyDeck }else if(kdr & KEY_SELECT){ trump = Trump_Destroy(trump); random = Random_Destroy(random); consoleSelect(&bottom_cons); printf("DestroyDeck & exit\n"); return 0; } } } //--------------------------------------------------------------------------------- void clearValue(void) { //--------------------------------------------------------------------------------- int i; for(i = 0;i < TRUMP_MAX + 1;i++){ card_num[i] = -1; } card_index = 0; } //--------------------------------------------------------------------------------- void drawDeck(Trump trump) { //--------------------------------------------------------------------------------- if(trump == NULL) return; consoleSelect(&top_cons); printf("\x01b[0;0HdrawDeck\n"); int i, j; int card_num[4], card_use[4]; for(i = 0;i < 13;i++){ for(j = 0;j < 4;j++){ card_num[j] = Trump_GetCardNumber(trump, i + (j * 13)); card_use[j] = (int)Trump_GetCardUse(trump, i + (j * 13)); } printf("\x01b[%d;0H %c%s,%01d %c%s,%01d %c%s,%01d %c%s,%01d\n", 2 + i, suit[ SET_SUIT(card_num[0]) ], rank[ SET_RANK(card_num[0]) ], card_use[0], suit[ SET_SUIT(card_num[1]) ], rank[ SET_RANK(card_num[1]) ], card_use[1], suit[ SET_SUIT(card_num[2]) ], rank[ SET_RANK(card_num[2]) ], card_use[2], suit[ SET_SUIT(card_num[3]) ], rank[ SET_RANK(card_num[3]) ], card_use[3] ); } printf("\nRemain %02d", Trump_GetCardRemain(trump)); } //---------------------------------------------------------------------------------
Trump.h
/*--------------------------------------------------------------------------------- Trump framework header version 0.01 May 16, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #ifndef _TRUMP_H_ #define _TRUMP_H_ #define RANK_NUM 13 #define SUIT_NUM 4 //#define JOKER_NUM 2 #define TRUMP_MAX (RANK_NUM * SUIT_NUM /* + JOKER_NUM */ ) #define SET_SUIT(n) ((n) / RANK_NUM) #define SET_RANK(n) ((n) % RANK_NUM) typedef struct _Deck *Trump; #ifdef __cplusplus extern "C" { #endif //トランプデッキを生成する。 Trump Trump_Create(void); //トランプデッキを破棄する。 Trump Trump_Destroy(Trump trump); //トランプデッキをクリア(初期化)する。 void Trump_Clear(Trump trump); //トランプデッキをシャッフルする。 void Trump_Shuffle(Trump trump, int seed, int shuffle_num); //トランプデッキにあるカード残数を返す。 int Trump_GetCardRemain(Trump trump); //トランプデッキにあるカード情報を返す。デッキインデックスは数字が若ものほど、上にあるカードを示している。 int Trump_GetCardNumber(Trump trump, int deck_index);//カード番号 bool Trump_GetCardUse(Trump trump, int deck_index);//カード使用中の有無 //トランプデッキにある一番上のカードを取得する。デッキに1枚もカードが無い場合 -1 が返る。 int Trump_GetCard(Trump trump); //トランプデッキにある任意のカードを取得する。カードがある場合そのカードが、使用中の場合 -1 が返る。 int Trump_RequestCard(Trump trump, int card_number); //トランプデッキの一番下にカードを戻す。 void Trump_SetCard(Trump trump, int card_number); #ifdef __cplusplus } #endif #endif // _TRUMP_H_
Trump.c
/*--------------------------------------------------------------------------------- Trump framework routine version 0.01 May 16, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #include <nds/ndstypes.h>//bool 型使用のためにインクルード。 #include "Deck.h" #include "Trump.h" //--------------------------------------------------------------------------------- Trump Trump_Create(void) { //--------------------------------------------------------------------------------- return Deck_Create(TRUMP_MAX); } //--------------------------------------------------------------------------------- Trump Trump_Destroy(Trump trump) { //--------------------------------------------------------------------------------- return Deck_Destroy(trump); } //--------------------------------------------------------------------------------- void Trump_Clear(Trump trump) { //--------------------------------------------------------------------------------- Deck_Clear(trump); } //--------------------------------------------------------------------------------- void Trump_Shuffle(Trump trump, int seed, int shuffle_num) { //--------------------------------------------------------------------------------- Deck_Shuffle(trump, seed, shuffle_num); } //--------------------------------------------------------------------------------- int Trump_GetCardRemain(Trump trump) { //--------------------------------------------------------------------------------- return Deck_GetCardRemain(trump); } //--------------------------------------------------------------------------------- int Trump_GetCardNumber(Trump trump, int deck_index) { //--------------------------------------------------------------------------------- return Deck_GetCardNumber(trump, deck_index); } //--------------------------------------------------------------------------------- bool Trump_GetCardUse(Trump trump, int deck_index) { //--------------------------------------------------------------------------------- return Deck_GetCardUse(trump, deck_index); } //--------------------------------------------------------------------------------- int Trump_GetCard(Trump trump) { //--------------------------------------------------------------------------------- return Deck_GetCard(trump); } //--------------------------------------------------------------------------------- int Trump_RequestCard(Trump trump, int card_number) { //--------------------------------------------------------------------------------- return Deck_RequestCard(trump, card_number); } //--------------------------------------------------------------------------------- void Trump_SetCard(Trump trump, int card_number) { //--------------------------------------------------------------------------------- Deck_SetCard(trump, card_number); } //---------------------------------------------------------------------------------
Deck.h
/*--------------------------------------------------------------------------------- Deck framework header version 0.01 May 16, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #ifndef _DECK_H_ #define _DECK_H_ typedef struct _Deck *Deck; #ifdef __cplusplus extern "C" { #endif //カードデッキを生成する。引数にはデッキで使用するカード枚数を指定する。 Deck Deck_Create(int card_max); //カードデッキを破棄する。 Deck Deck_Destroy(Deck deck); //カードデッキをクリア(初期化)する。 void Deck_Clear(Deck deck); //カードデッキをシャッフルする。 void Deck_Shuffle(Deck deck, int seed, int shuffle_num); //カードデッキにあるカード残数を返す。 int Deck_GetCardRemain(Deck deck); //カードデッキにあるカード情報を返す。デッキインデックスは数字が若ものほど、上にあるカードを示している。 int Deck_GetCardNumber(Deck deck, int deck_index);//カード番号 bool Deck_GetCardUse(Deck deck, int deck_index);//カード使用中の有無 //カードデッキにある一番上のカードを取得する。デッキに1枚もカードが無い場合 -1 が返る。 int Deck_GetCard(Deck deck); //カードデッキにある任意のカードを取得する。カードがある場合そのカードが、使用中の場合 -1 が返る。 int Deck_RequestCard(Deck deck, int card_number); //カードデッキの一番下にカードを戻す。 void Deck_SetCard(Deck deck, int card_number); #ifdef __cplusplus } #endif #endif // _DECK_H_
Deck.c
/*--------------------------------------------------------------------------------- Deck framework routine version 0.01 May 16, 2010 By REGEKATSU ---------------------------------------------------------------------------------*/ #include <stdlib.h> #include <nds/ndstypes.h>//bool 型使用のためにインクルード。 #include "../libmy/Random.h" #include "Deck.h" typedef struct{ int number; bool use; }Card; typedef struct _Deck{ Card *card; int deck_index; int card_max; int card_remain; Random random; }_Deck; #define SET_DECK_INDEX(idx) (((idx) >= deck->card_max) ? idx - deck->card_max:idx) #define PREV_DECK_INDEX(idx) (((idx) <= 0) ? deck->card_max - 1:idx - 1) #define NEXT_DECK_INDEX(idx) (((idx) >= deck->card_max - 1) ? 0:idx + 1) void deck_SwapCard(Card *a, Card *b); //--------------------------------------------------------------------------------- Deck Deck_Create(int card_max) { //--------------------------------------------------------------------------------- Deck deck; deck = (Deck)malloc(sizeof(_Deck)); deck->card_max = (card_max <= 0) ? 1 : card_max; deck->card = malloc(sizeof(Card) * deck->card_max); deck->random = Random_Create(GENERATOR_LCGS); Deck_Clear(deck); return deck; } //--------------------------------------------------------------------------------- Deck Deck_Destroy(Deck deck) { //--------------------------------------------------------------------------------- if(deck == NULL) return NULL; deck->random = Random_Destroy(deck->random); free(deck->card); free(deck); return NULL; } //--------------------------------------------------------------------------------- void Deck_Clear(Deck deck) { //--------------------------------------------------------------------------------- if(deck == NULL) return; int i; for(i = 0;i < deck->card_max;i++){ deck->card[i].number = i; deck->card[i].use = false; } deck->card_remain = deck->card_max; deck->deck_index = 0; } //--------------------------------------------------------------------------------- void Deck_Shuffle(Deck deck, int seed, int shuffle_num) { //--------------------------------------------------------------------------------- if(deck == NULL) return; int i, a, b; Random_SetSeed(deck->random, seed); for(i = 0;i < shuffle_num;i++){ a = Random_GetValue(deck->random) % deck->card_max; b = Random_GetValue(deck->random) % deck->card_max; deck_SwapCard(&deck->card[a], &deck->card[b]); } } //--------------------------------------------------------------------------------- int Deck_GetCardRemain(Deck deck) { //--------------------------------------------------------------------------------- if(deck == NULL) return -1; return deck->card_remain; } //--------------------------------------------------------------------------------- int Deck_GetCardNumber(Deck deck, int deck_index) { //--------------------------------------------------------------------------------- if(deck == NULL) return -1; if(deck_index < 0 || deck_index >= deck->card_max) return -1; return deck->card[SET_DECK_INDEX(deck->deck_index + deck_index)].number; } //--------------------------------------------------------------------------------- bool Deck_GetCardUse(Deck deck, int deck_index) { //--------------------------------------------------------------------------------- if(deck == NULL) return -1; if(deck_index < 0 || deck_index >= deck->card_max) return -1; return deck->card[SET_DECK_INDEX(deck->deck_index + deck_index)].use; } //--------------------------------------------------------------------------------- int Deck_GetCard(Deck deck) { //--------------------------------------------------------------------------------- if(deck == NULL) return -1; if(deck->card_remain == 0) return -1; int ret; while(deck->card[deck->deck_index].use == true){ deck->deck_index = NEXT_DECK_INDEX(deck->deck_index); } deck->card[deck->deck_index].use = true; deck->card_remain--; ret = deck->card[deck->deck_index].number; deck->deck_index = NEXT_DECK_INDEX(deck->deck_index); return ret; } //--------------------------------------------------------------------------------- int Deck_RequestCard(Deck deck, int card_number) { //--------------------------------------------------------------------------------- if(deck == NULL) return -1; if(card_number < 0 || card_number >= deck->card_max) return -1; if(deck->card_remain == 0) return -1; int i; for(i = 0;i < deck->card_max;i++){ if(deck->card[i].number == card_number && deck->card[i].use == false){ deck->card[i].use = true; deck->card_remain--; return deck->card[i].number; } } return -1; } //--------------------------------------------------------------------------------- void Deck_SetCard(Deck deck, int card_number) { //--------------------------------------------------------------------------------- if(deck == NULL) return; if(card_number < 0 || card_number >= deck->card_max) return; if(deck->card_remain == deck->card_max) return; int i; Card temp ={0, false}; //1,戻すカードの元ある位置にあるカード情報を一時退避する。 //但し、使用中でないカードを戻す要求だった場合、処理を中断して関数を終了する。 for(i = 0;i < deck->card_max;i++){ if(deck->card[i].number == card_number){ if(deck->card[i].use == false) return; deck->card[i].use = false; deck->card_remain++; temp = deck->card[i]; break; } } //2,戻すカードの元あった位置を始点として現在のデッキ終点までの値を全て一つ前にずらす。 while(i != PREV_DECK_INDEX(deck->deck_index)){ deck_SwapCard(&deck->card[i], &deck->card[NEXT_DECK_INDEX(i)]); i = NEXT_DECK_INDEX(i); } //3,一時退避してた戻すカードの情報をデッキ終点へ書き込み関数を終了する。 deck->card[ PREV_DECK_INDEX(deck->deck_index) ] = temp; } //--------------------------------------------------------------------------------- void deck_SwapCard(Card *a, Card *b) { //--------------------------------------------------------------------------------- Card temp; temp = *a; *a = *b; *b = temp; } //---------------------------------------------------------------------------------