到达游戏初始状态后,撤消功能无法正常工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了到达游戏初始状态后,撤消功能无法正常工作相关的知识,希望对你有一定的参考价值。

我正在尝试为我的电路板构建一个返回上一个电路板状态的撤销功能。我还构建了一个临时保存功能,可以创建一个包含所有以前游戏状态的列表。但是当我撤消直到棋盘达到初始游戏状态(全部为空白)然后进行移动时,让我们在4x4板中说A3,撤销功能无法回到初始状态(全部为空白)并且它保存了当前状态作为董事会的第一个状态,所以最初的空白状态消失了......

如果有人知道我可能做错了什么,请评论。任何帮助表示赞赏。

我是初学程序员,但我希望我对这个问题的解释非常有用。接下来我将临时保存功能放在撤销功能和我称为董事会状态的结构中:

这是董事会成员国的结构:

typedef struct state *stateptr;
struct state {
char **table;
stateptr prev;
};

extern stateptr last=NULL;

遵循tmpSave函数:

void tmpSave(char **table,int dim)
{
//dim is the dimension of the dim x dim board and i have a main 
//function that calls tmpSave after each move with the above parameters
int i,j;
stateptr newstate;
newstate=malloc(sizeof(struct state));

newstate->table=malloc(dim*sizeof(char*));
for(i=0; i<dim; i++)
{
    newstate->table[i]=malloc(dim*sizeof(char));
}

for(i=0; i<dim; i++)
{
    for(j=0; j<dim; j++)
    {
        newstate->table[i][j]=table[i][j];
    }
}
    if(last!=NULL)
    {
        newstate->prev=last;
        last=newstate;
    }
    else
    {
        printf("
Hi!!
");
        last=newstate;
        last->prev=NULL;
    }
}

最后,undo函数返回一个将在main函数中正确打印的表,START标志确定我们是否处于初始(空白)状态:

char **undo(short int *START)
{
stateptr prev=last->prev;
if(last->prev==NULL)
{
    printf("
Can't further undo
");
}
else
{
    free(last);
    last=prev;

}
if(last->prev==NULL) *START=1;

return last->table;
}

例如:1。首先是董事会是空白的2.Move: 0 0 0 0 w 0 0 0 0 0 0 0 0 0 0 0 3.另一招: 0 0 w 0 w 0 0 0 0 0 0 0 0 0 0 0 4.undo直到初始(空白状态) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 此时'last'指针等于初始状态所以last-> prev = NULL并且* START变为1,这个用于定义由bot玩家完成的移动(不要认真考虑)

5.另一招: 0 0 0 w 0 0 0 0 0 0 0 0 0 0 0 0 6.Undo状态(这里描述的问题出现): 0 0 0 w 0 0 0 0 0 0 0 0 0 0 0 0 虽然它应该是: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (初始空白状态)..

之后,初始状态是假的,状态为'w'(1,4)。

答案

由于这个例子并不完整,我认为tablelast是全局的,而DIM是一个常数。 在开始时调用tmpSave存储空白板的副本。 在结构中,将table作为char (*table)[DIM]类型可以为每个调用分配和释放内存。它还可以更轻松地将内容复制到table和存储的副本。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define DIM 4

struct state {
    char (*table)[DIM];
    struct state *prev;
};

struct state *last = NULL;
char table[DIM][DIM];

void tmpSave ( )
{
    struct state *newstate = NULL;

    newstate = malloc ( sizeof ( *newstate));//allocate structure

    newstate->table = malloc ( sizeof table);//allocate table

    memmove (newstate->table, table, sizeof table);//copy table

    if ( last != NULL)
    {
        newstate->prev = last;
        last = newstate;
    }
    else
    {
        printf ( "
Hi!!
");
        last = newstate;
        last->prev = NULL;
    }
}

void undo ( void)
{
    struct state *prev = last->prev;

    if ( last->prev == NULL)
    {
        printf ( "
Can't further undo
");
    }
    else
    {
        free ( last->table);//free table
        free ( last);//free structure
        last = prev;
        memmove ( table, last->table, sizeof table);//copy saved table back to table
    }
}

void showboard ( void)
{
    int i = 0;
    for ( i = 0; i < DIM; ++i)
    {
        printf ( "%.*s
", DIM, table[i]);//no zero terminator so print only DIM number of characters
    }
}

struct state *freestate ( struct state *all)
{
    //make sure all structures are free
    while ( all) {
        struct state *tmp = all;
        free ( all->table);//free table
        free ( all);//free structure
        all = tmp->prev;
    }
    return NULL;
}

int main( void) {

    srand ( time ( NULL));//seed random number generator

    memset ( table, '0', sizeof table);//set table to all 0
    showboard ( );
    tmpSave ( last);//make sure empty table is saved

    for ( int each = 0; each < DIM; ++each) {//DIM moves
        int row = rand ( ) % DIM;
        int col = rand ( ) % DIM;

        table[col][row] = each + '1';
        tmpSave ( last);//save table

        printf ( "	Move %d
", each + 1);
        showboard ( );
    }
    for ( int each = 0; each < DIM + 1; ++each) {//undo DIM + 1
        printf ( "	undo %d
", each + 1);
        undo ( );
        showboard ( );
    }

    last = freestate ( last);

    return 0;
}

要在运行时输入dim,请使用char **table并根据需要进行分配。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct State state;
struct State {
    char **table;
    state *prev;
};

state *tmpSave ( state *last, int dim, char **table) {
    state *newstate = NULL;

    if ( NULL == ( newstate = malloc ( sizeof ( *newstate)))) {//allocate structure
        fprintf ( stderr, "malloc newstate problem
");
        return last;
    }

    if ( NULL == ( newstate->table = malloc ( sizeof *newstate->table * dim))) {//allocate table pointers
        fprintf ( stderr, "malloc newstate->table problem
");
        free ( newstate);
        return last;
    }

    for ( int each = 0; each < dim; ++each) {
        if ( NULL == ( newstate->table[each] = malloc ( sizeof **newstate->table * dim))) {//chars to pointers
            fprintf ( stderr, "malloc newstate->table[each] problem
");
            while ( each--) {
                free ( newstate->table[each]);
            }
            free ( newstate->table);
            free ( newstate);
            return last;
        }
        memmove ( newstate->table[each], table[each], dim);//copy table
    }

    if ( last != NULL) {
        newstate->prev = last;
        last = newstate;
    }
    else {
        printf ( "
Hi!!
");
        last = newstate;
        last->prev = NULL;
    }

    return last;
}

state *undo ( state *last, int dim, char **table) {
    state *prev = last->prev;

    if ( last->prev == NULL) {
        printf ( "Can't further undo
");
    }
    else {
        for ( int each = 0; each < dim; ++each) {
            free ( last->table[each]);//free chars
        }
        free ( last->table);//free table pointers
        free ( last);//free structure
        last = prev;
        for ( int each = 0; each < dim; ++each) {
            memmove ( table[each], last->table[each], dim);//copy saved table back to table
        }
    }

    return last;
}

void showboard ( int dim, char **table) {
    int show = 0;
    for ( show = 0; show < dim; ++show) {
        printf ( "%.*s
", dim, table[show]);//no zero terminator so print only dim number of characters
    }
}

state *freeall ( state *all, int dim) {
    //make sure all structures are free
    while ( all) {
        state *tmp = all;
        for ( int each = 0; each < dim; ++each) {
            free ( all->table[each]);//free chars
        }
        free ( all->table);//free pointers
        free ( all);//free structure
        all = tmp->prev;
    }
    return NULL;
}

int main( void) {
    char input[100] = "";
    int dim = 0;
    int scanned = 0;
    char extra = 0;
    char **table = NULL;
    state *last = NULL;

    srand ( time ( NULL));//seed random number generator

    do {
        if ( 1 != scanned) {
            printf ( "enter a number only. try again
");
        }
        printf ( "enter a number
");
        if ( fgets ( input, sizeof input, stdin)) {
            scanned = sscanf ( input, "%d %c", &dim, &extra);
        }
        else {
            fprintf ( stderr, "fgets problem
");
            return 0;
        }
    } while ( 1 != scanned);

    if ( NULL == ( table = malloc ( sizeof *table * dim))) {//allocate pointers
        fprintf ( stderr, "problem malloc table
");
        return 0;
    }
    for ( int each = 0; each < dim; ++each) {
        if ( NULL == ( table[each] = malloc ( sizeof **table * dim))) {//allocate chars to pointers
            fprintf ( stderr, "problem malloc table[each]
");
            while ( each--) {
                free ( table[each]);
            }
            free ( table);
            return 0;
        }
        memset ( table[each], '-', dim);//set chars to all -
    }

    showboard ( dim, table);
    last = tmpSave ( last, dim, table);//make sure empty table is saved

    for ( int move = 0; move < dim; ++move) {//dim number of random moves
        int row = rand ( ) % dim;
        int col = rand ( ) % dim;

        table[col][row] = move + 'A';
        last = tmpSave ( last, dim, table);//save table

        printf ( "	Move %d of %d
", move + 1, dim);
        showboard ( dim, table);
        printf ( "press enter
");
        if ( ! fgets ( input, sizeof input, stdin)) {
            fprintf ( stderr, "fgets problem
");
            last = freeall ( last, dim);
            return 0;
        }
    }
    for ( int move = 0; move < dim + 1; ++move) {//try to undo dim + 1 moves
        printf ( "	undo %d of %d
", move + 1, dim + 1);
        last = undo ( last, dim, table);
        showboard ( dim, table);
        printf ( "press enter
");
        if ( ! fgets ( input, sizeof input, stdin)) {
            fprintf ( stderr, "fgets problem
");
            last = freeall ( last, dim);
            return 0;
        }
    }

    last = freeall ( last, dim);

    return 0;
}

以上是关于到达游戏初始状态后,撤消功能无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

后堆栈在 Jetpack Navigation 中无法正常工作

从片段调用 Google Play 游戏服务

由于我删除了 phpMyadmin 中的表,Php artisan 无法正常工作,如何撤消此操作?

使用 savedInstanceState 保存片段状态

unity动画一个片段播放完怎么让它不会到初始状态

帆布迷宫游戏流畅的动画