- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于这个项目,我的老师给了我代码,它是 1024/2048 游戏的文本版本。游戏开始时,用户从棋盘上的两个数字开始(2 或 4)。然后每次移动都会弹出一个新数字,如果两个相邻数字具有相同的值,它们将加在一起形成这些数字的总和。我必须创建一个节点,这样我才能撤消所做的每一步。我已经成功地能够将每个 Action 传递到节点中。但是当我调用我的 goBack 函数来撤消移动时,它只显示相同的板。这是代码,任何人都可以发现我做错了什么吗?
#include <iostream>
#include <iomanip> // used for setting output field size using setw
#include <cstdlib>
using namespace std;
typedef struct Node {
int *board;// keep track of board
int *score; // keep track of score
int *boardSize; // keep track of the board size
struct Node* pNext; // node pointer
}Node;
Node* goBack(Node* pHead) {
if (pHead != NULL) {
// create a temp pointer to hold the original head
Node* temp = pHead;
// pHead is pointing to next one
pHead = pHead->pNext;
// free the orinal head's memory!!
delete temp;
}
return pHead;
}
Node* addNode(Node* pHead, int board[], int boardSize, int score ) {
// create a new node, and set the letter and count
Node* newNodePtr = new Node();
newNodePtr->board = board;
newNodePtr->boardSize = &boardSize;
newNodePtr->score = &score;
// insert it at the beginning (new node's next is set to original head)
newNodePtr->pNext = pHead;
cout<<"here";
// return the new node's point (which will be the new head)
return newNodePtr;
}
//--------------------------------------------------------------------
// Display ID info
void displayIDInfo()
{
cout << "Dale Reed \n";
cout << "UIC CS 141, Spring 2014 \n";
cout << "Welcome to 1024 and More. \n";
cout << "This program is based off of Gabriele Cirulli's game online at \n";
cout << " bit.ly/great2048 \n";
cout << " \n";
}//end displayIDInfo()
//--------------------------------------------------------------------
// Display Instructions
void displayInstructions()
{
cout << "For each move enter a direction as a letter key, as follows: \n"
<< " W \n"
<< " A S D \n"
<< "where A=left,W=up, D=right and S=down. \n"
<< " \n"
<< "After a move, when two identical valued tiles come together they \n"
<< "join to become a new single tile with the value of the sum of the \n"
<< "two originals. This value gets added to the score. On each move \n"
<< "one new randomly chosen value of 2 or 4 is placed in a random open \n"
<< "square. User input of x exits the game. \n"
<< " \n";
}//end displayInstructions()
//--------------------------------------------------------------------
// Place a randomly selected 2 or 4 into a random open square on
// the board.
void placeRandomPiece( int board[], int boardSize)
{
// Randomly choose a piece to be placed (2 or 4)
int pieceToPlace = 2;
if( rand()%2 == 1) {
pieceToPlace = 4;
}
// Find an unoccupied square that currently has a 0
int index;
do {
index = rand() % (boardSize*boardSize);
}while( board[ index] != 0);
// board at position index is blank, so place piece there
board[ index] = pieceToPlace;
}//end placeRandomPiece()
//--------------------------------------------------------------------
// Prompt for and get board size, dynamically allocate space for the
// board, initialize the board and set the max tile value that
// corresponds to the board size.
void getSizeAndSetBoard( int * &board, // board that is dynamically allocated
int * &previousBoard, // space for copy of board
int &boardSize, // size of the board, entered by user
int &maxTileValue) // max tile value, depending on board size
{
// Prompt for board size and set corresponding game end value
// cout << "Enter the size board you want, between 4 and 12: ";
// cin >> boardSize;
// Allocate space for the 2-d board (and board copy), stored as a 1-d array
board = new int[ boardSize * boardSize]; // e.g. a board of size 4 will have 4x4=16 elements
previousBoard = new int[ boardSize * boardSize];
// Initialize board to all 0's
for( int row=0; row<boardSize; row++) {
for( int col=0; col<boardSize; col++ ) {
board[ row*boardSize + col] = 0;
}
}
// Calculate and display game ending value
for( int i=4; i<boardSize; i++) {
maxTileValue = maxTileValue * 2; // double for each additional board dimension > 4
}
cout << "Game ends when you reach " << maxTileValue << "." << endl;
// Set two random pieces to start game
placeRandomPiece( board, boardSize);
placeRandomPiece( board, boardSize);
}//end getSizeAndSetBoard()
//--------------------------------------------------------------------
// Display the Board
void displayBoard( int *board, int boardSize, int score)
{
// Set display width value depending on boardSize (and corresponding max value)
int displayWidth;
switch( boardSize) {
case 4:
case 5:
case 6:
case 7: displayWidth = 5; break; // up to 8,192
case 8:
case 9:
case 10: displayWidth = 6; break; // up to 65,536
case 11:
case 12: displayWidth = 7; break; // up to 262,144
default:
// Sanity check, should never get here
cout << "Invalid boardSize of " << boardSize
<< ". Exiting program..\n" << endl;
exit( -1);
break;
}
cout << "\n"
<<"Score: " << score << endl;
for( int row=0; row<boardSize; row++) {
cout << " ";
for( int col=0; col<boardSize; col++ ) {
int current = row*boardSize + col; // 1-d index corresponding to row & col
cout << setw( 6); // set output field size to 6 (Requires #include <iomanip> )
// display '.' if board value is 0
if( board[ current] == 0) {
cout << '.';
}
else {
cout << board[ current];
}
}
cout << "\n\n";
}
}//end displayBoard()
//--------------------------------------------------------------------
// Make a copy of the board. This is used after an attempted move
// to see if the board actually changed.
void copyBoard(
int previousBoard[], // destination for board copy
int board[], // board from which copy will be made
int boardSize) // size of the board
{
for( int row=0; row<boardSize; row++) {
for( int col=0; col<boardSize; col++ ) {
int current = row*boardSize + col; // 1-d index corresponding to row & col
previousBoard[ current] = board[ current];
}
}
}//end copyBoard()
//--------------------------------------------------------------------
// See if board changed this turn. If not, no additional piece
// is randomly added and move number does not increment in main().
// Returns true if boards are different, false otherwise.
bool boardChangedThisTurn( int previousBoard[], int board[], int boardSize)
{
// Compare element by element. If one is found that is different
// then return true, as board was changed.
for( int row=0; row<boardSize; row++) {
for( int col=0; col<boardSize; col++ ) {
int current = row*boardSize + col; // 1-d index corresponding to row & col
if( previousBoard[ current] != board[ current]) {
return true;
}
}
}
return false; // No board difference was found
}
// While the 4 functions below (slideLeft(), slideRight(), slideUp(), slideDown() ) could
// be all combined into a single function, that single function would be difficult to
// understand, so these 4 functions were left separate.
//--------------------------------------------------------------------
// Slide all tiles left, combining matching values, updating the score
void slideLeft( int board[], int boardSize, int &score)
{
// handle each row separately
for( int row=0; row<boardSize; row++) {
// set index limit for this row to be index of left-most tile on this row
int limit = row * boardSize;
// Start from the second column and process each element from left to right
for( int col=1; col<boardSize; col++) {
// get 1-d array index based on row and col
int current = row * boardSize + col;
// slide current piece over as far left as possible
while( board[ current-1] == 0 && current > limit) {
board[ current-1] = board[ current];
board[ current] = 0;
current--;
}
// Combine it with left neighbor if values are the same and non zero.
// The additional check for (current > limit) ensures a tile can be combined
// at most once on a move, since limit is moved right every time a combination is made.
// This ensures a row of: 2 2 4 4 ends up correctly as: 4 8 0 0 and not: 8 4 0 0
if( (board[ current-1] == board[ current]) && (board[ current] != 0) && (current > limit)) {
board[ current-1] = board[ current-1] + board[ current];
board[ current] = 0;
limit = current; // Reset row index limit, to prevent combining a piece more than once
score += board[ current-1]; // Update score
}
}//end for( int col...
}//end for( int row...
}//end slideLeft()
//--------------------------------------------------------------------
// Slide all tiles right, combining matching values, updating the score
void slideRight( int board[], int boardSize, int &score)
{
// handle each row separately
for( int row=0; row<boardSize; row++) {
// set index limit for this row to be index of right-most tile on this row
int limit = row * boardSize + boardSize - 1;
// Start from the second-to-last column and process each element from right to left
for( int col=boardSize - 1; col>=0; col--) {
// get 1-d array index based on row and col
int current = row * boardSize + col;
// slide current piece over as far right as possible
while( board[ current+1] == 0 && current < limit) {
board[ current+1] = board[ current];
board[ current] = 0;
current++;
}
// Combine it with right neighbor if values are the same and non zero.
// The additional check for (current < limit) ensures a tile can be combined
// at most once on a move, since limit is moved left every time a combination is made.
// This ensures a row of: 4 4 2 2 ends up correctly as: 0 0 8 4 and not: 0 0 4 8
if( (board[ current+1] == board[ current]) && (board[ current] != 0) && (current < limit)) {
board[ current+1] = board[ current+1] + board[ current];
board[ current] = 0;
limit = current; // Reset row index limit, to prevent combining a piece more than once
score += board[ current+1]; // Update score
}
}//end for( int col...
}//end for( int row...
}//end slideRight()
//--------------------------------------------------------------------
// Slide all tiles up, combining matching values, updating the score
void slideUp( int board[], int boardSize, int &score)
{
// handle each column separately
for( int col=0; col<boardSize; col++) {
// set index limit for this column to be index of top-most tile on this row
int limit = col;
// Start from the second row and process each element from top to bottom
for( int row=1; row<boardSize; row++) {
// get 1-d array index based on row and col
int current = row * boardSize + col;
// slide current piece up as far as possible
while( board[ current-boardSize] == 0 && current > limit) {
board[ current-boardSize] = board[ current];
board[ current] = 0;
current = current - boardSize;
}
// Combine it with upper neighbor if values are the same and non zero.
// The additional check for (current > limit) ensures a tile can be combined
// at most once on a move, since limit is moved down every time a combination is made.
if( (board[ current-boardSize] == board[ current]) && (board[ current] != 0) && (current > limit)) {
board[ current-boardSize] = board[ current-boardSize] + board[ current];
board[ current] = 0;
limit = current; // Reset row index limit, to prevent combining a piece more than once
score += board[ current-boardSize]; // Update score
}
}//end for( int col...
}//end for( int row...
}//end slideUp()
//--------------------------------------------------------------------
// Slide all tiles down, combining matching values, updating the score
void slideDown( int board[], int boardSize, int &score)
{
// handle each column separately
for( int col=0; col<boardSize; col++) {
// set index limit for this column to be index of bottom-most tile on this row
int limit = (boardSize - 1) * boardSize + col;
// Start from the next to last row and process each element from bottom to top
for( int row=boardSize-1; row>=0; row--) {
// get 1-d array index based on row and col
int current = row * boardSize + col;
// slide current piece down as far as possible
while( board[ current+boardSize] == 0 && current < limit) {
board[ current+boardSize] = board[ current];
board[ current] = 0;
current = current + boardSize;
}
// Combine it with lower neighbor if values are the same and non zero.
// The additional check for (current < limit) ensures a tile can be combined
// at most once on a move, since limit is moved up every time a combination is made.
if( (board[ current+boardSize] == board[ current]) && (board[ current] != 0) && (current < limit)) {
board[ current+boardSize] = board[ current+boardSize] + board[ current];
board[ current] = 0;
limit = current; // Reset row index limit, to prevent combining a piece more than once
score += board[ current+boardSize]; // Update score
}
}//end for( int col...
}//end for( int row...
}//end slideDown()
//--------------------------------------------------------------------
// Return true if we're not done, false if we *are* done
// Game is done if board is full and no more valid moves can be made
// or if a tile with maxTileValue has been created.
bool notDone( int board[], // current board
int boardSize, // size of one side of board
int maxTileValue) // max tile value for this size board
{
// See if the maxTileValue is found anywhere on the board.
// If so, game is over.
for( int i=0; i<boardSize*boardSize; i++) {
if( board[ i] == maxTileValue) {
cout << "Congratulations! You made it to " << maxTileValue << " !!!" << endl;
return false; // there are open squares, so we are not done yet
}
}
// See if there are any open squares. If so return true since we aren't done
for( int i=0; i<boardSize*boardSize; i++) {
if( board[ i] == 0) {
return true; // there are open squares, so we are not done yet
}
}
// All squares are full.
// To check if board is done, make a copy of board, then slide left
// and slide down. If resulting board is same as original, we are done
// with game since there are no moves to be made.
int *boardCopy = new int[ boardSize * boardSize];
copyBoard( boardCopy, board, boardSize);
int tempScore = 0; // used as a placeHolder only for function calls below
slideLeft( boardCopy, boardSize, tempScore);
slideDown( boardCopy, boardSize, tempScore);
// Compare each square of boards. If any is different, a move is possible
for( int i=0; i<boardSize*boardSize; i++) {
if( boardCopy[ i] != board[ i]) {
return true; // Game is not done
}
}
cout << "\n"
<< "No more available moves. Game is over.\n"
<< "\n";
return false; // Game is done since all squares are full and there are no moves
}//end notDone()
//--------------------------------------------------------------------
int main()
{
Node *pHead = NULL;
int score = 0;
int boardSize = 4; // user will enter this value. Set default to 4
int *board; // space will be dynamically allocated depending on user selected size
int *previousBoard; // store copy of board, used to see if a move changed the board
int maxTileValue = 1024; // 1024 for 4x4 board, 2048 for 5x5, 4096 for 6x6, etc.
char userInput = ' '; // handles user input
int move = 1; // user move counter
// Display ID info and instructions
displayIDInfo();
displayInstructions();
// get the board size, create and initialize the board, and set the max tile value
getSizeAndSetBoard( board, previousBoard, boardSize, maxTileValue);
// Main loop to display board, prompt for and handle move and check for win
do {
// Display the board
displayBoard( board, boardSize, score);
// Copy board. After attempting a move this is used to verify that the board
// changed, which allows randomly placing an additional piece on board and
// updating the move number.
copyBoard( previousBoard, board, boardSize); // copy from board into previousBoard
// Prompt for and handle user input
cout << move << ". Your move: ";
cin >> userInput;
switch (userInput) {
case 'x':
cout << "Thanks for playing. Exiting program...";
exit( 0);
break;
case 'r':
cout << "\n"
<< "Resetting board \n"
<< "\n";
getSizeAndSetBoard( board, previousBoard, boardSize, maxTileValue);
score = 0;
move = 1;
continue; // go back up to main loop and restart game
break;
case 'a':
slideLeft( board, boardSize, score); // Slide left
pHead = addNode(pHead, board, boardSize, score);
break;
case 's':
slideDown( board, boardSize, score); // Slide down
pHead = addNode(pHead, board, boardSize, score);
break;
case 'd':
slideRight( board, boardSize, score); // Slide right
pHead = addNode(pHead, board, boardSize, score);
break;
case 'w':
slideUp( board, boardSize, score); // Slide up
pHead = addNode(pHead, board, boardSize, score);
break;
case'u':
pHead = goBack(pHead);// go back
break;
case 'p':
// Place a piece on the board
int index; // 1-d array index location to place piece
int value; // value to be placed
cin >> index >> value;
board[ index] = value;
continue; // Do not increment move number or place random piece
break;
default:
cout << "Invalid input, please retry.";
continue;
break;
}//end switch( userInput)
// If the move resulted in pieces changing position, then it was a valid move
// so place a new random piece (2 or 4) in a random open square and update move number.
if( boardChangedThisTurn( previousBoard, board, boardSize)) {
// Place a random piece on board
placeRandomPiece( board, boardSize);
// Update move number after a valid move
move++;
}
// clear the screen, which is system("clear") on UNIX and system("cls") on Windows
//system("clear");
system("cls");
}while( notDone( board, boardSize, maxTileValue));
// Display final board
displayBoard( board, boardSize, score);
cout << "Exiting program...\n\n";
return 0;
}//end main()
最佳答案
newNodePtr->board = board;
您不要在此处复制棋盘。相反,您将指针复制到板。所以你所有的“节点”都存储指向同一个棋盘的指针(这是游戏的当前状态)。
您需要通过分配和复制整个数组来复制板的内容。
关于c++ - 在 C++ 中使用节点撤消 Board 上的移动!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23303040/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!