这破玩意儿写了好久,代码又长又丑。
实在是拿不出手的东西。。。。而且估计还是有很多bug,从老哥结婚准备那天开始零零散散地写到现在,果然写代码战线拖太长不行啊。。。。
姑且写了很长, 在这里放出来
首先这是他们老师放出来的.h,代码之所以很乱也有原因是要实现他们老师要求的function!!!(其实是自己菜吧)
一个是对game的限制:
// The game of Final Card-Down. v1.1.2
//
// !!! DO NOT CHANGE THIS FILE !!!
#include "Card.h"
#ifndef GAME_H
#define GAME_H
#define NUM_PLAYERS 4
#define NOT_FINISHED -1
#define NO_WINNER 4
#define FALSE 0
#define TRUE (!FALSE)
typedef struct _game *Game;
typedef enum {
// Clockwise is 0 -> 1 -> 2 -> 3 -> 0 ...
CLOCKWISE,
// Anticlockwise is 0 -> 3 -> 2 -> 1 -> 0 ...
ANTICLOCKWISE
} direction;
typedef enum {
// Draw a single card from the deck.
DRAW_CARD,
// Play a single card onto the discard pile.
PLAY_CARD,
// Say the word "UNO".
SAY_UNO,
// Say the word "DUO".
SAY_DUO,
// Say the word "TRIO".
SAY_TRIO,
// End the player's turn.
END_TURN
} action;
typedef struct _playerMove {
// Which action to play.
action action;
// Declare which color must be played on the next turn.
// This is only used when playing a DECLARE.
color nextColor;
// Which card to play (only valid for PLAY_CARD).
Card card;
} playerMove;
// Create a new game engine.
//
// This creates a game with a deck of the given size
// and the value, color, and suit of each card to be taken from
// each of the arrays in order.
//
// Your game will always have 4 players. Each player starts with a hand
// of 7 cards. The first card from the deck is given to player 0, the
// second to player 1, the third to player 2, the fourth to player 3,
// the fifth to player 0, and so on until each player has 7 cards.
Game newGame(int deckSize, value values[], color colors[], suit suits[]);
// Destroy an existing game.
//
// This should free all existing memory used in the game including
// allocations for players and cards.
void destroyGame(Game game);
// The following functions can be used by players to discover
// information about the state of the game.
// Get the number of cards that were in the initial deck.
int numCards(Game game);
// Get the number of cards in the initial deck of a particular
// suit.
int numOfSuit(Game game, suit suit);
// Get the number of cards in the initial deck of a particular color.
int numOfColor(Game game, color color);
// Get the number of cards in the initial deck of a particular value.
int numOfValue(Game game, value value);
// Get the number of the player whose turn it is.
int currentPlayer(Game game);
// Get the current turn number.
//
// The turn number increases after a player ends their turn.
// The turn number should start at 0 once the game has started.
int currentTurn(Game game);
// Get the number of points for a given player.
// Player should be between 0 and 3.
//
// This should _not_ be called by a player.
int playerPoints(Game game, int player);
// Get the current direction of play.
direction playDirection(Game game);
// This function returns the number of turns that have occurred in the
// game so far including the current turn.
// When using either the turnMoves or pastMove function,
// the turn number should be less than the number of moves that this
// function returns.
// (i.e. on turn 0 of the game, this should return 1, as there has been
// 1 turn so far including the current turn; if you called pastMove you
// would need to call it on turn 0, as this is the only possible value
// less than 1.)
int numTurns(Game game);
// Get the number of moves that happened on a turn.
//
// A turn may consist of multiple moves such as drawing cards,
// playing cards, and ending the turn.
int turnMoves(Game game, int turn);
// Look at a previous move from a specified turn.
playerMove pastMove(Game game, int turn, int move);
// Get the number of cards in a given player's hand.
int playerCardCount(Game game, int player);
// Get the number of cards in the current player's hand.
int handCardCount(Game game);
// View a card from the current player's own hand.
//
// The player should not need to free() this card,
// so you should not allocate or clone an existing card
// but give a reference to an existing card.
Card handCard(Game game, int card);
// Check if a given move is valid.
//
// If the last player played a 2 (DRAW_TWO),
// the next player must either play a 2
// or draw 2 cards.
// Otherwise, the player must play a card that is either a ZERO
// or that has the same color, value, or suit as the card on the top
// of the discard pile.
//
// If the player plays an ADVANCE, the next player's turn is skipped.
// If the player plays a BACKWARDS, the direction of play is reversed.
// If the player plays a CONTINUE, they may play another card.
// If the player plays a DECLARE, they must also state which color
// the next player's discarded card should be.
//
// A player can only play cards from their hand.
// A player may choose to draw a card instead of discarding a card.
// A player must draw a card if they are unable to discard a card.
//
// This check should verify that:
// * The card being played is in the player's hand
// * The player has played at least one card before finishing their turn,
// unless a draw-two was played, in which case the player may not
// play a card, and instead must draw the appropriate number of cards.
int isValidMove(Game game, playerMove move);
// Play the given action for the current player
//
// If the player makes the END_TURN move, their turn ends,
// and it becomes the turn of the next player.
//
// This should _not_ be called by the player AI.
void playMove(Game game, playerMove move);
// Check the game winner.
//
// Returns NOT_FINISHED if the game has not yet finished,
// 0-3, representing which player has won the game, or
// NO_WINNER if the game has ended but there was no winner.
int gameWinner(Game game);
#endif // GAME_H
// The playing card interface. v1.1.0
//
// !!! DO NOT CHANGE THIS FILE !!!
//
// This interface represents a single playing card
// in the game of Final Card-Down.
#ifndef CARD_H
#define CARD_H
typedef struct _card *Card;
// The various colors that a card can have.
typedef enum {
RED,
BLUE,
GREEN,
YELLOW,
PURPLE
} color;
// The various suits that a card can have.
typedef enum {
HEARTS,
DIAMONDS,
CLUBS,
SPADES,
QUESTIONS
} suit;
// The various values that a card can have.
typedef enum {
ZERO,
ONE,
DRAW_TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN,
EIGHT,
NINE,
ADVANCE,
BACKWARDS,
CONTINUE,
DECLARE,
E,
F
} value;
// Create a new card.
// These values can only be set at creation time.
// The number should be between 0x0 and 0xF.
Card newCard(value value, color color, suit suit);
// Destroy an existing card.
void destroyCard(Card card);
// Get the card's suit (HEARTS, DIAMONDS, etc).
suit cardSuit(Card card);
// Get the card's number (0x0 through 0xF).
value cardValue(Card card);
// Get the card's color (RED, BLUE, etc).
color cardColor(Card card);
#endif // CARD_H
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include "Game.h"
#include "Card.h"
using namespace std;
#define MAX_DECK_SIZE 100
#define MAX_TURNS 100
#define MAX_MOVE 15
struct cardPile{
int card[MAX_DECK_SIZE];
int num;
};
struct _game{
int deckSize;
int numPlayers;
int moveInTurn[MAX_TURNS];
int nowPlayer;
int lastPlayer;
int isFirstTurn;
int twoValue;
int haveDraw;
int havePlay;
int haveSayUno;
int haveSayDuo;
int haveSayTrio;
int lastForgetO;
int noWinner;
int points;
int playerPoints[NUM_PLAYERS];
int turns;
playerMove *lastMove;
playerMove *pastMoveRec[MAX_TURNS][MAX_MOVE];
cardPile player[NUM_PLAYERS];
cardPile disPile;
direction nowDirection;
color *colors;
suit *suits;
value *values;
};
struct _card{
value value;
color color;
suit suit;
};
Card newCard(value value, color color, suit suit){
Card card = (_card*)calloc(1, sizeof(_card));
card->value = value;
card->color = color;
card->suit = suit;
return card;
}
playerMove *newPlayerMove(){
playerMove *p = (playerMove*)calloc(1, sizeof(playerMove));
p->card = newCard(ZERO, RED, HEARTS);
return p;
}
void destroyPlayerMove(playerMove *p){
destroyCard(p->card);
free(p);
}
Game newGame(int deckSize, value values[], color colors[], suit suits[]){
Game nowGame = (_game*)calloc(1, sizeof(_game));
nowGame->deckSize = deckSize;
nowGame->disPile.num = 0;
for(int i=0;i<NUM_PLAYERS;i++){
nowGame->player[i].num = 0;
}
nowGame->turns = 0;
nowGame->nowDirection = CLOCKWISE;
nowGame->twoValue = 0;
nowGame->nowPlayer = 0;
nowGame->haveDraw = FALSE;
nowGame->havePlay = FALSE;
nowGame->haveSayUno = FALSE;
nowGame->haveSayDuo = FALSE;
nowGame->haveSayTrio = FALSE;
nowGame->noWinner = FALSE;
nowGame->points = 0;
nowGame->lastMove = newPlayerMove();
for(int i = 0; i<MAX_TURNS; i++){
for(int j = 0; j<MAX_MOVE; j++){
nowGame->pastMoveRec[i][j] = newPlayerMove();
}
}
nowGame->values = values;
nowGame->colors = colors;
nowGame->suits = suits;
return nowGame;
};
int isOver(Game game){
if(game->noWinner == TRUE) return TRUE;
int sum = 0;
for(int i=0;i<NUM_PLAYERS;i++){
sum += game->player[i].num;
}
if(sum==0) return TRUE;
else return FALSE;
}
void dealCard(Game game){
int i,j,k;
k = 0, j = 0;
int p = game->deckSize;
for(i=0;i<28;i++){
j = i%NUM_PLAYERS;
game->player[j].card[k] = --p;
++game->player[j].num;
if(j==3){
++k;
}
}
game->deckSize -= 28;
}
void systemVoice(Game game){
printf("Player %d's turn\n",game->nowPlayer);
printf("you have %d cards,there are:\n",game->player[game->nowPlayer].num);
printf("index: ");
for(int i = 0;i<game->player[game->nowPlayer].num;i++){
printf("%d ",game->player[game->nowPlayer].card[i]);
}
printf("\n");
printf("value: ");
for(int i = 0;i<game->player[game->nowPlayer].num;i++){
printf("%d ",game->values[game->player[game->nowPlayer].card[i]]);
}
printf("\n");
printf("color: ");
for(int i = 0;i<game->player[game->nowPlayer].num;i++){
printf("%d ",game->colors[game->player[game->nowPlayer].card[i]]);
}
printf("\n");
printf("suit: ");
for(int i = 0;i<game->player[game->nowPlayer].num;i++){
printf("%d ",game->suits[game->player[game->nowPlayer].card[i]]);
}
printf("\n");
printf("Please select your action: \n");
printf("0: DRAW_CARD\n1:PLAY_CARD\n2:SAY_UNO\n3:SAY_DUO\n4:SAY_TRIO\n5:END_TURN\n");
}
int drawACard(Game game, int playerIndex){
int numOfMyCards = game->player[playerIndex].num;
if(game->deckSize > 0){
game->player[playerIndex].card[numOfMyCards++] = game->deckSize - 1;
game->deckSize -= 1;
game->player[playerIndex].num = numOfMyCards;
return TRUE;
}else if(game->disPile.num > 0){
game->player[playerIndex].card[numOfMyCards++] = game->disPile.card[game->disPile.num - 1];
game->disPile.num -= 1;
game->player[playerIndex].num = numOfMyCards;
return TRUE;
}else{
return FALSE;
}
}
void discard(Game game, int playerIndex, int cardIndex){
int numOfDispile = game->disPile.num;
int numOfCardsOnHand = game->player[playerIndex].num;
game->disPile.card[numOfDispile++] = cardIndex;
for(int i = 0; i<numOfCardsOnHand; i++){
if(game->player[playerIndex].card[i] == cardIndex){
for(int j = i+1; j < numOfCardsOnHand; j++){
game->player[playerIndex].card[j-1] = game->player[playerIndex].card[j];
}
}
}
game->disPile.num = numOfDispile;
game->player[playerIndex].num = numOfCardsOnHand - 1;
}
void copyLastMove(Game game, playerMove &move){
game->lastMove->action = PLAY_CARD;
game->lastMove->card->value = move.card->value;
game->lastMove->card->color = move.card->color;
game->lastMove->card->suit = move.card->suit;
}
int isValidMove(Game game, playerMove move){
if(game->lastMove->card->value == ADVANCE){
if(move.action == END_TURN){
game->isFirstTurn = TRUE;
return TRUE;
}
printf("This turn you are been skipped ...invalid action!\n");
return FALSE;
}
if(move.action == PLAY_CARD){
if(game->havePlay != FALSE){
printf("You have no change to play.... invalid action\n");
return FALSE;
}
if(game->haveDraw == TRUE){
printf("You can't played now.... invalid action\n");
return FALSE;
}
if(game->lastMove->card->value == DRAW_TWO){
if(move.card->value != DRAW_TWO){
printf("You can only play card whose value is 2, or draw %d cards\n", game->twoValue);
return FALSE;
}else{
game->twoValue += 2;
game->havePlay = TRUE;
copyLastMove(game, move);
return TRUE;
}
}else if(game->lastMove->card->value == DECLARE){
if(move.card->color != game->lastMove->nextColor){
printf("You can't play this color\n");
return FALSE;
}else{
copyLastMove(game, move);
game->havePlay = TRUE;
return TRUE;
}
}
if(game->lastMove->card->value == move.card->value || game->lastMove->card->color == move.card->suit || game->lastMove->card->suit == move.card->suit || game->isFirstTurn || move.card->value == ZERO){
copyLastMove(game, move);
if(game->isFirstTurn == TRUE){
game->isFirstTurn = FALSE;
}
if(move.card->value == DRAW_TWO){
game->havePlay = TRUE;
game->twoValue += 2;
return TRUE;
}else if(move.card->value == ADVANCE){
game->havePlay = TRUE;
return TRUE;
}else if(move.card->value == BACKWARDS){
game->nowDirection = (direction)(!game->nowDirection);
game->havePlay = TRUE;
return TRUE;
}else if(move.card->value == CONTINUE){
game->haveDraw = -1; //fuck up... For the Draw action
game->isFirstTurn = TRUE;
return TRUE;
}else if(move.card->value == DECLARE){
copyLastMove(game, move);
game->havePlay = TRUE;
return TRUE;
}else{
game->havePlay = TRUE;
return TRUE;
}
}else{
printf("What are you thinking? Invalid card\n");
return FALSE;
}
}else if(move.action == DRAW_CARD){
if(game->haveDraw == TRUE && game->twoValue == 0){
printf("You have drawed... invalid action\n");
return FALSE;
}
if(game->haveDraw == -1 || game->havePlay == TRUE){
printf("You have chosen to play card... invalid action\n");
return FALSE;
}
game->haveDraw = TRUE;
if(drawACard(game, game->nowPlayer)){
if(game->twoValue>0){
-- game->twoValue;
}
return TRUE;
}else{
printf("No cards left....No winner\n");
return -1; //No winner;
}
}else if(move.action == SAY_UNO){
game->haveSayUno = TRUE;
if(game->lastForgetO == 1){
for(int i = 1; i<=2;i++){
drawACard(game, game->lastPlayer);
}
}
printf("UNO!!\n");
return TRUE;
}else if(move.action == SAY_DUO){
game->haveSayDuo = TRUE;
if(game->lastForgetO == 2){
for(int i=1; i<=2; i++){
drawACard(game, game->lastPlayer);
}
}
printf("DUO!!\n");
return TRUE;
}else if(move.action == SAY_TRIO){
game->haveSayTrio = TRUE;
if(game->lastForgetO == 3){
for(int i=1; i<=2; i++){
drawACard(game, game->lastPlayer);
}
}
}else{
if(game->havePlay==FALSE && game->haveDraw == FALSE){
printf("Nothong has been done\n");
return FALSE;
}
return 2;
}
printf("wtf?!\n");
return FALSE;
}
void initBeforeMove(Game game){
game->haveDraw = FALSE;
game->havePlay = FALSE;
game->haveSayUno = FALSE;
game->haveSayDuo = FALSE;
game->haveSayTrio = FALSE;
}
void playMove(Game game, playerMove move){
//emmmmmmmmmmmmm
}
void copyMove(playerMove *a, playerMove *b){
a->action = b->action;
a->nextColor = b->nextColor;
a->card = b->card;
}
void makeMove(Game game){
int isOver = FALSE;
playerMove *nowMove = newPlayerMove();
int num, flag, cardIndex;
initBeforeMove(game);
while (isOver == FALSE) {
if(game->player[game->nowPlayer].num == 0){
printf("No cards! Congarduations\n");
game->playerPoints[game->nowPlayer] = game->points++;
break;
}
systemVoice(game);
scanf("%d",&nowMove->action);
if(nowMove->action==PLAY_CARD){
printf("pelase input the index of the card\n");
scanf("%d",&num);
cardIndex = num;
nowMove->card->color = game->colors[num];
nowMove->card->suit = game->suits[num];
nowMove->card->value = game->values[num];
nowMove->action = PLAY_CARD;
if(game->values[num] == DECLARE){
printf("Please select the color which the next player need to play\n");
printf("0:RED, 1:BLUE, 2:GREEN, 3:YELLOW, 4:PURPLE\n");
while(scanf("%d", &num)&&(num<0||num>4)){
printf("invalid color!\n");
}
nowMove->nextColor = (color)num;
}
flag = isValidMove(game, *nowMove);
if(flag == TRUE){
discard(game, game->nowPlayer, cardIndex);
}
}else{
flag = isValidMove(game, *nowMove);
if(flag == -1){
game->noWinner = TRUE;
}else if(flag == 2){
isOver = TRUE;
}
}
copyMove(game->pastMoveRec[game->turns][game->moveInTurn[game->turns]], nowMove);
++(game->moveInTurn[game->turns]);
}
if(game->player[game->nowPlayer].num == 1 && game->haveSayUno == FALSE){
game->lastForgetO = 1;
}else if(game->player[game->nowPlayer].num == 2 && game->haveSayDuo == FALSE){
game->lastForgetO = 2;
}else if(game->player[game->nowPlayer].num == 3 && game->haveSayTrio == FALSE){
game->lastForgetO = 3;
}
destroyPlayerMove(nowMove);
}
void playGame(Game game){
dealCard(game);
printf("Welcome to Uno World, the loser will go die\n");
game->isFirstTurn = TRUE;
game->lastMove->card->value = ZERO, game->lastMove->card->color = RED, game->lastMove->card->suit = HEARTS;
game->twoValue = 0;
while(!isOver(game)){
makeMove(game);
int add;
if(game->nowDirection == CLOCKWISE) add = 1;
else add = -1;
game->nowPlayer = (game->nowPlayer + add + NUM_PLAYERS)%NUM_PLAYERS;
game->turns++;
}
printf("The game is over\n");
}
void destroyCard(Card card){
free(card);
}
suit cardSuit(Card card){
return card->suit;
}
value cardValue(Card card){
return card->value;
}
color cardColor(Card card){
return card->color;
}
void destroyGame(Game game){
destroyPlayerMove(game->lastMove);
for(int i = 0; i<MAX_TURNS; i++){
for(int j = 0; j<MAX_MOVE; j++){
destroyPlayerMove(game->pastMoveRec[i][j]);
}
}
free(game);
}
int numCards(Game game){
return game->deckSize;
}
int numOfSuit(Game game, suit suit){
int sum = 0;
for(int i = 0; i<game->deckSize; i++){
if(game->suits[i] == suit){
++sum;
}
}
return sum;
}
int numOfColor(Game game, color color){
int sum = 0;
for(int i = 0; i<game->deckSize; i++){
if(game->colors[i] == color){
++sum;
}
}
return sum;
}
int numOfValue(Game game, value value){
int sum = 0;
for(int i = 0; i<game->deckSize; i++){
if(game->values[i] == value){
++sum;
}
}
return sum;
}
int currentPlayer(Game game){
return game->nowPlayer;
}
int currentTurn(Game game){
return game->turns;
}
int playerPoints(Game game, int player){
return game->playerPoints[player];
}
direction playDirection(Game game){
return game->nowDirection;
}
int numTurns(Game game){
return game->turns + 1;
}
int turnMoves(Game game, int turn){
return game->moveInTurn[turn];
}
playerMove pastMove(Game game, int turn, int move){
return *game->pastMoveRec[turn][move];
}
int playerCardCount(Game game, int player){
return game->player[player].num;
}
int handCardCount(Game game){
return game->player[game->nowPlayer].num;
}
Card handCard(Game game, int card){
int index;
for(int i = 0; i<game->player[game->nowPlayer].num; i++){
if(i==card){
index = game->player[game->nowPlayer].card[i];
}
}
Card ca = newCard(game->values[index], game->colors[index], game->suits[index]);
return ca;
}
int gameWinner(Game game){
for(int i = 0; i<NUM_PLAYERS; i++){
if(game->playerPoints[i] == 0){
return i;
}
}
return NO_WINNER;
}
int main(){
value a[50];
color b[50];
suit c[50];
for(int i = 0; i<30; i++){
scanf("%d",a+i);
}
for(int i = 0; i<30; i++){
scanf("%d",b+i);
}
for(int i = 0; i<30; i++){
scanf("%d",c+i);
}
Game killme = newGame(30, a, b, c);
playGame(killme);
destroyGame(killme);
return 0;
}