我在构建游戏的最后一块(卡片的功能)时遇到麻烦。如果您不熟悉UNO的规则,请https://www.unorules.com/
我的问题是我不确定如何构建“反向”和“跳过”功能。我有一个“玩家”对象向量,通过迭代来控制谁转弯。
在我的脑海中,这似乎很简单。跳过只会将索引增加一个,跳过先前的播放器对象,而反向将减少索引而不是增加索引,因此会向后移动。
我似乎无法将此想法应用到代码中。
这是我的第一个大型项目,我对所有代码感到有些不知所措。
我已经建立了一个跳过功能,但是实际上没有放任何东西,因为我不知道从哪里开始。我觉得自己在每个回合中迭代的方式效率低下,而且杂乱无章,因此我可能需要一些帮助来进行重构。
编辑: 这是我认为可以接受的反向代码
void Game::round(Player& player, Deck& deck)
{
// 1 round has x turns
for (int i = 0; i < amountOfPlayers; i++)
{
if (reverse = true) //reverse is not defined in below code
{
for (int i; i < amountOfPlayers; i--)
{
if (i < 0)
{
i = playerVector.size()-1;
}
turns(player, deck, i);
}
}
turns(player, deck, i);
}
}
这是我的游戏代码
#pragma once
#include "Player.h"
#include "DevTest.h"
class Player;
class DevTest;
class Deck;
class Global;
#include <string>
#include <vector>
class Game
{
private:
int amountOfPlayers;
std::vector<Player*> playerVector;
std::vector<Card> inPlay; //cards in play
public:
Game();
void createPlayerVector(Deck& deck);
void menu(Deck &deck, Player &player, Game game, DevTest devtest);
void round(Player& player, Deck& deck);
void turns(Player &player, Deck &deck, int i);
bool win(Player& player);
void playGame(Player& player, Game game, Deck& deck);
bool chooseCard(Player& player, Deck deck, int position);
void drawTwo(Deck &deck, int drawAmount, int playerIndex);
void drawWild(Deck& deck, int cardNum, int playerIndex, int toChoose);
void skip(Player player, Deck& deck, int i);
~Game();
};
/*
#include "Game.h"
class DevTest;
Game::Game()
{
Deck deck;
}
void Game::createPlayerVector(Deck &deck)
{
std::string userName;
std::cout << "Please enter the amount of players: ";
std::cin >> amountOfPlayers;
if (amountOfPlayers < 2 || amountOfPlayers>10)
{
if (amountOfPlayers < 2)
{
std::cout << "Sorry! Not enough players." << std::endl;
}
if (amountOfPlayers > 10)
{
std::cout << "Sorry! Too many players." << std::endl;
}
}
else
{
std::cout << "Please enter the names of each player." << std::endl;
for (int i = 0; i < amountOfPlayers; i++)
{
Player* player = new Player;
playerVector.push_back(player);
std::cout << "Player " << i+1 << ": ";
std::cin.ignore();
std::getline(std::cin, userName);
this->playerVector[i]->setUserName(userName);
this->playerVector[i]->setHand(deck, *player);
player->printHand(deck);
}
}
system("PAUSE");
system("CLS");
return;
}
void Game::menu(Deck& deck, Player& player, Game game, DevTest devtest)
{
int choice;
std::cout << "UNO" << std::endl;
std::cout << "1. Play Game" << std::endl;
std::cout << "2. Read Rules" << std::endl;
std::cout << "3. Developer Testing" << std::endl;
std::cout << "4. Quit" << std::endl;
do
{
std::cin >> choice;
switch (choice)
{
case 1:
std::cout << "Play Game" << std::endl;
break;
case 2:
std::cout << "Read Rules" << std::endl;
break;
case 3:
std::cout << "Developer Testing" << std::endl;
devtest.testMenu(deck, player, game);
break;
case 4:
exit(0);
break;
default:
std::cout << "Invalid choice. Please choose again." << std::endl;
}
//clear screen
} while (choice < 1 || choice >4);
}
void Game::round(Player& player, Deck& deck)
{
// 1 round has x turns
for (int i = 0; i < amountOfPlayers; i++)
{
turns(player, deck, i);
}
}
void Game::turns(Player& player, Deck& deck, int playerIndex)
{
int option;
bool proceed = false;
do
{
std::cout << "It is currently " << playerVector[playerIndex]->getUserName() << "'s" << " turn." << std::endl << std::endl;
std::cout << "The card you must match is: " << std::endl;
deck.toString(inPlay.front().color);
std::cout << " " << inPlay.front().value << std::endl << std::endl;
std::cout << "[1] Draw Card " << std::endl;
std::cout << "[2] Play Card" << std::endl;
std::cout << "Pick an option. " << std::endl;
std::cin >> option;
if (option == 1)
{
//draw card
deck.dealCard(*playerVector[playerIndex]);
std::cout << "You have taken a card." << std::endl;
}
if (option == 2)
{
//use card, transfer hand to bottom of deck
proceed = chooseCard(player, deck, playerIndex);
}
if (win(player) == true)
{
//end game, celebrate
return;
}
system("PAUSE");
system("CLS");
} while (proceed == false);
}
bool Game::win(Player& player)
{
if (player.isEmpty(player) == true)
{
//you win
//std::cout << "Congratulations, " << player.getUserName() << " you win!" << std::endl;
//return true;
}
else
{
//nobody has won yet
return false;
}
return false;
}
void Game::playGame(Player& player, Game game, Deck& deck)
{
//cout intro();
deck.createDeck();
deck.shuffle();
createPlayerVector(deck);
//start off game by placing a single card down
inPlay.push_back(deck.getCard());
deck.pop();
//remove choose card from hand
//pop off deck to start game (starting card)
while (win(player) == false)
{
round(player, deck);
}
}
bool Game::chooseCard(Player& player, Deck deck, int playerIndex) //delete from hand, populate inPlay
{
int toChoose;
bool validate = false;
std::cout << "Which card would you like to choose? Press 0 to draw a card." << std::endl;
while (validate == false)
{
this->playerVector[playerIndex]->printHand(deck);
std::cin >> toChoose;
if (toChoose == 0)
{
//fix
deck.dealCard(*playerVector[playerIndex]); //fix
return false;
}
if (playerVector[playerIndex]->getHandCard(player, toChoose).value == 13 || playerVector[playerIndex]->getHandCard(player, toChoose).value == 14)
{
validate = true;
int cardNum = playerVector[playerIndex]->getHandCard(player, toChoose).value;
drawWild(deck, cardNum, playerIndex, toChoose);
}
else if (playerVector[playerIndex]->getHandCard(player, toChoose).value != inPlay.front().value && playerVector[playerIndex]->getHandCard(player, toChoose).color != inPlay.front().color)
{
//card doesn't match
validate = false;
std::cout << "You are not allowed to play this card!" << std::endl;
return false;
}
validate = true;
}
if (validate == true)
{
if (playerVector[playerIndex]->getHandCard(player, toChoose).value == 10 || playerVector[playerIndex]->getHandCard(player, toChoose).value == 14)
{
int drawAmount = 0;
//draw two
if (playerVector[playerIndex]->getHandCard(player, toChoose).value == 10)
{
int drawAmount = 2;
drawTwo(deck, drawAmount, playerIndex + 1);
}
}
if(playerVector[playerIndex]->getHandCard(player, toChoose).value == 11 || playerVector[playerIndex]->getHandCard(player, toChoose).value == 12)
{
skip(player, deck, playerIndex);
}
inPlay.insert(inPlay.begin(), playerVector[playerIndex]->getHandCard(player, toChoose));
playerVector[playerIndex]->deleteHand(toChoose);
return true;
}
return true;
}
void Game::drawTwo(Deck &deck, int drawAmount, int playerIndex)
{
if (playerIndex>playerVector.size()-1)
{
playerIndex = 0; //circular code
}
for (int j = 0; j < drawAmount; j++)
{
deck.dealCard(*playerVector[playerIndex]);
}
}
void Game::drawWild(Deck& deck, int cardNum, int playerIndex, int toChoose) //fix
{
if (cardNum == 13)
{
int choice;
//wild
std::cout << "What color would you like to choose?" << std::endl;
std::cout << "[1] BLUE" << std::endl;
std::cout << "[2] GREEN" << std::endl;
std::cout << "[3] RED" << std::endl;
std::cout << "[4] YELLOW" << std::endl;
std::cin >> choice;
//inPlay.front().color = static_cast<Card::Color>(choice - 1);
//
}
if (cardNum == 14)
{
//draw 4
//lets u pick a color AND next person draws 4
}
}
void Game::skip(Player player, Deck& deck, int i)
{
//turns(player, deck, i + 1);
}
Game::~Game()
{
}
玩家定义为
#pragma once
#include <vector>
#include <iostream>
#include "Deck.h"
#include "Card.h"
class Deck;
class Player
{
private:
int length;
std::string username; //can indicate whos turn / wins
static const int HANDSIZE = 7;
std::vector<Card> hand;
public:
Player();
void pushHand(Card deck);
void deleteHand(int position);
void printHand(Deck deck);
void setHand(Deck &deck, Player& player);
Card getHandCard(Player& player, int position);
int getHANDSIZE();
std::string getUserName();
void setUserName(std::string name);
bool isEmpty(Player& player); //hand is empty
~Player();
};
#include "Player.h"
class Player;
Player::Player()
{
this->length = 0;
}
void Player::pushHand(Card deck)
{
//push 1 deck object into hand
this->hand.push_back(deck);
length++;
}
void Player::deleteHand(int position)
{
for (int i = 0; i < hand.size(); i++)
{
if (i == position-1)
{
hand.erase(hand.begin()+i);
}
}
}
void Player::printHand(Deck deck)
{
for (int i = 0; i < hand.size(); i++)
{
std::cout << i+1 << ". ";
std::cout << "Color: ";
deck.toString(hand[i].color);
std::cout << " | " << "Value: " << hand[i].value << std::endl;
}
}
void Player::setHand(Deck &deck, Player& player) //used only for setting hand at beginning of game
{
for (int i = 0; i < HANDSIZE; i++)
{
deck.dealCard(player);
}
}
Card Player::getHandCard(Player& player, int position)
{
return this->hand[position - 1];
//return player.hand[position - 1];
}
int Player::getHANDSIZE()
{
return HANDSIZE;
}
std::string Player::getUserName()
{
return username;
}
void Player::setUserName(std::string name)
{
username = name;
}
bool Player::isEmpty(Player& player)
{
if (length == 0)
{
return true;
}
return false;
}
Player::~Player()
{
//delete hand;
}
甲板是
#pragma once
#include "Card.h"
#include "Player.h"
#include <iostream>
#include <ctime>
class Player;
class Deck
{
private:
static const int MAXSIZE = 108; //108 cards in UNO
int length;
public:
Deck();
void createDeck();
void shuffle();
void printDeck();
//void push();
void pop();
int top();
bool isEmpty();
bool isFull();
void toString(Card::Color color); //converts enum to string.
void dealCard(Player &player);
Card getCard();
Card* deck;
~Deck();
};
#include "Deck.h"
Deck::Deck()
{
deck = new Card[MAXSIZE];
length = 0;
}
void Deck::createDeck()
{
//UNO has 4 zero cards
int num = 0;
for (int col = 0; col <= 3; col++)
{
deck[length].value = num; //sets each to zero
deck[length].color = static_cast<Card::Color>(col); //sets each card to a color, iterates through enum
length++;
}
//card value 1-9 , draw-two (10), skip (11), reverse (12)
for (num = 1; num <= 12; num++)
{
for (int x = 0; x < 2; x++)
{
for (int col = 0; col <= 3; col++)
{
deck[length].value = num;
deck[length].color = static_cast<Card::Color>(col);
length++;
}
}
}
//wild(13) and draw four(14)
for (num = 13; num <= 14; num++)
{
for (int x = 0; x < 4; x++)
{
deck[length].value = num;
deck[length].color = Card::Color::WILD;
length++;
}
}
}
void Deck::shuffle() //fisher-yates algorithm
{
srand(time(NULL));
for (int i = length - 1; i > 0; i--)
{
int j = (rand() % (i + 1));
std::swap(deck[j], deck[i]);
}
}
void Deck::printDeck()
{
for (int i = 0; i < length; i++)
{
std::cout << "Length: " << i << std::endl;
std::cout << "Value: " << deck[i].value << std::endl;
std::cout << "Color: ";
toString(deck[i].color);
}
}
void Deck::pop()
{
if (isEmpty() == false)
{
length--;
}
}
int Deck::top()
{
if (isEmpty() == false)
{
return length - 1;
}
return 0;
}
bool Deck::isEmpty()
{
if (length == 0)
{
return true;
}
return false;
}
bool Deck::isFull()
{
if (length >= MAXSIZE)
{
return true;
}
return false;
}
void Deck::toString(Card::Color color)
{
switch (color)
{
case Card::Color::BLUE:
std::cout << "Blue";
break;
case Card::Color::GREEN:
std::cout << "Green";
break;
case Card::Color::RED:
std::cout << "Red";
break;
case Card::Color::YELLOW:
std::cout << "Yellow";
break;
case Card::Color::WILD:
std::cout << "Wild";
break;
}
return;
}
void Deck::dealCard(Player &player)
{
player.pushHand(deck[top()]);
pop();
return;
}
Card Deck::getCard()
{
return deck[length-1];
}
Deck::~Deck()
{
}
甲板中每张卡的位置
#pragma once
class Card
{
private:
public:
enum Color { BLUE, GREEN, RED, YELLOW, WILD };
Card();
Color color;
int value;
Card(Color color, int value);
~Card();
};
#include "Card.h"
Card::Card()
{
}
Card::Card(Color color, int value)
{
color = this->color;
value = this->value;
}
Card::~Card()
{
}
答案 0 :(得分:0)
我认为您可以将迭代int放入Game的成员m_currentIterator中,并将迭代方向设置为bool m_isReversed(true = normal,false = reversed)。
当玩家使用“ Reverse”卡时,您只需将m_isReversed更改为!m_isReversed;并在相反的if(m_isReversed)i--否则i ++中进行迭代。
当播放器使用“跳过”时,您只需使用m_currentIterator ++;
我知道这不是最好的方法,也不是丑陋的代码(使用愚蠢的成员),但是效果很好:)