首页 > 解决方案 > 蛇和梯子板 - 输出不打印出来

问题描述

我正在尝试使用 C 编程制作蛇和梯子游戏的棋盘。稍后我尝试使用坐标作为动作,但现在我似乎无法将板子打印出来,我不知道为什么。

这就是代码的样子

#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <windows.h>

void displayboard(int ACROSS, int UPDOWN)
{

char x[50] = {};
char y[50] = {};

x[ACROSS] = 'x';
y[UPDOWN] = 'y';


printf("\n\t  ________ ________ ________ ________ ________ ________ ________ ________ ________ ________ ");
printf("\n\t | GO  TO |        |        |        |        |        |        |  GO TO |        |        |");
printf("\n\t | BOX 49 |        |        |        |        |        |        |  BOX 1 |        |  WIN!  |");
printf("\n\t |   %d   |   %d   |   %d   |   %d   |   %d   |   %d   |   %d   |   %d   |   %d   |   %d   |",41,42,43,44,45,46,47,48,49,50);
printf("\n\t |        |        |        |        |        |        |        |        |        |        |");
printf("\n\t |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |" ,x[40],y[40],x[41],y[41],x[42],y[42],x[43],y[43],x[44],y[44],x[45],y[45],x[46],y[46],x[47],y[47],x[48],y[48],x[49],y[49]);
printf("\n\t |________|________|________|________|________|________|________|________|________|________|");
printf("\n\t |   REV  |        |        |        | GO TO  |        |        |        |        |  PAUSE |");
printf("\n\t | 10STEP |        |        |        | BOX 11 |        |        |        |        | 2 TURNS|");
printf("\n\t |   %d   |   %d   |   %d   |   %d   |  %d    |   %d   |   %d   |  %d    |  %d    |   %d   |",40,39,38,37,36,35,34,33,32,31);
printf("\n\t |        |        |        |        |        |        |        |        |        |        |");
printf("\n\t |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |",x[39],y[39],x[38],y[38],x[37],y[37],x[36],y[36],x[35],y[35],
                x[34],y[34],x[33],y[33],x[32],y[32],x[31],y[31],x[30],y[30]);
printf("\n\t |________|________|________|________|________|________|________|________|________|________|");
printf("\n\t |        |  GO TO |        |        |        |        |        |        |        |        |");
printf("\n\t |        | BOX 33 |        |        |        |        |        |        |        |        |");
printf("\n\t |   %d   |   %d   |   %d   |   %d   |  %d    |   %d   |   %d   |   %d   |   %d   |   %d   |",21,22,23,24,25,26,27,28,29,30);
printf("\n\t |        |        |        |        |        |        |        |        |        |        |");
printf("\n\t |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |",x[20],y[20],x[21],y[21],x[22],y[22],x[23],y[23],x[24],y[24],
                x[25],y[25],x[26],y[26],x[27],y[27],x[28],y[28],x[29],y[29]);
printf("\n\t |________|________|________|________|________|________|________|________|________|________|");
printf("\n\t |        |        | GO TO  |        |        |        |        |        |        |        |");
printf("\n\t |        |        | BOX 40 |        |        |        |        |        |        |        |");
printf("\n\t |   %d   |   %d   |   %d   |   %d   |  %d    |   %d   |   %d   |   %d   |   %d   |   %d   |",20,19,18,17,16,15,14,13,12,11);
printf("\n\t |        |        |        |        |        |        |        |        |        |        |");
printf("\n\t |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |",x[19],y[19],x[18],y[18],x[17],y[17],x[16],y[16],x[15],y[15],
                x[14],y[14],x[13],y[13],x[12],y[12],x[11],y[11],x[10],y[10]);
printf("\n\t |________|________|________|________|________|________|________|________|________|________|");
printf("\n\t |        |  PAUSE |        |        |        |        |        |  REV   |        |        |");
printf("\n\t |        | 1 TURN |        |        |        |        |        | 3 STEP |        |        |");
printf("\n\t |  %2d    |   %2d   |   %2d   |   %2d   |   %2d   |   %2d   |   %2d   |   %2d   |   %2d   |   %2d   |",1,2,3,4,5,6,7,8,9,10);
printf("\n\t |        |        |        |        |        |        |        |        |        |        |");
printf("\n\t |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |   %c %c    |",x[0],y[0],x[1],y[1],x[2],y[2],x[3],y[3],x[4],y[4],
                x[5],y[5],x[6],y[6],x[7],y[7],x[8],y[8],x[9],y[9]);
printf("\n\t |________|________|________|________|________|________|________|________|________|________|");
printf("\n");
}

我知道它看起来真的很乱,因为我最近才开始学习 C,但这是我目前能想到的最好的。虽然,如果有更好的选择,我愿意阅读它。任何帮助深表感谢。

标签: c

解决方案


除了底部的小格式错误外,它打印得很好。
看这里。

但是请注意,编写此类游戏时,不适合使用标准 C 打印,因为它不允许您自由移动光标或清除之前打印的内容,因此您无法更新已打印到屏幕的内容. 不确定 Windows 是否提供了一种简单的方法,但在大多数其他系统上它有点复杂并且非常依赖于系统,这就是为什么人们使用像Ncurses这样的库。它不适用于 Windows,但名为PDCurses的库可用。它的代码是公共领域的(你可以以任何你喜欢的方式使用它)并且可以在 GitHub 上找到

更新

也许我说得太早了。当然,如果您知道确切的屏幕尺寸(行数和每行的列数),您总是可以打印整个屏幕,这将导致整个屏幕被刷新。看看我写的这个演示代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <limits.h>
#include <stdbool.h>
#include <math.h>
#include <float.h>
#include <time.h>

#if defined (__WIN32__)
#   include <windows.h>
#else
#   include <unistd.h>
#endif

#define TERM_WIDTH    80
#define TERM_HEIGHT   25
#define STAR_COUNT  1000

static const float STAR_SPEED = 1.5;
static const unsigned SPACE_DEPTH = 70;
static const unsigned FRAME_DURATION = 24;
static const char BANNER_TEXT[] = "This is awesome!!!";

struct Star {
    float x;
    float y;
    float z;
};

static unsigned gBannerPosition;
static struct Star gStars[STAR_COUNT];
static char gBanner[2 * TERM_WIDTH];
static char gScreen[TERM_HEIGHT][TERM_WIDTH];

static
void sleepForMS ( unsigned milliseconds ) {
#if defined (__WIN32__)
    Sleep(milliseconds);
#else
    usleep(milliseconds * 1000);
#endif
}

static
void clearScreen ( ) {
    memset(gScreen, ' ', sizeof(gScreen));
}

static
void printScreen ( ) {
    printf("%.*s", (int)sizeof(gScreen), (char *)gScreen);
    fflush(stdout);
}

static
void animateBanner ( ) {
    const int line = (TERM_HEIGHT / 2);
    memcpy(gScreen[line], &gBanner[gBannerPosition], sizeof(gScreen[line]));
    gBannerPosition--;
    if (gBannerPosition == 0) {
        gBannerPosition = sizeof(gScreen[12]);
    }
}

static
struct Star spawnNewStar ( bool randomZ )  {
    return (struct Star){
        .x = (float)random() / INT_MAX * 50 - 25,
        .y = (float)random() / INT_MAX * 50 - 25,
        .z = randomZ ?
                ((float)random() / INT_MAX * SPACE_DEPTH - 1) + 1
                : SPACE_DEPTH
    };
}

static
void animateStars ( ) {
    for (unsigned s = 0; s < STAR_COUNT; s++) {
        gStars[s].z -= STAR_SPEED;
        if (gStars[s].z <= 0) {
            gStars[s] = spawnNewStar(false);
        }
        float zFactor = 128.f / (gStars[s].z + FLT_MIN);
        int x = round(gStars[s].x * zFactor + (TERM_WIDTH / 2));
        int y = round(gStars[s].y * zFactor + (TERM_HEIGHT / 2));
        if (x >= 0 && x < TERM_WIDTH && y >= 0 && y < TERM_HEIGHT) {
            float starSize = (SPACE_DEPTH - gStars[s].z) / SPACE_DEPTH;
            char starSign = '#';
            if (starSize < 0.25) {
                starSign = '.';
            } else if (starSize < 0.5) {
                starSign = '+';
            } else if (starSize < 0.75) {
                starSign = '*';
            }
            gScreen[y][x] = starSign;
        }
    }
}

static
void initStars ( ) {
    srandom(time(NULL));
    for (unsigned s = 0; s < STAR_COUNT; s++) {
        gStars[s] = spawnNewStar(true);
    }
}

static
size_t minsize ( size_t a, size_t b ) { return a < b ? a : b; }

static
void initBanner ( ) {
    memset(gBanner, ' ', sizeof(gBanner));
    memcpy(gBanner, BANNER_TEXT,
        minsize(sizeof(BANNER_TEXT) - 1, TERM_WIDTH)
    );
    memcpy(&gBanner[TERM_WIDTH], BANNER_TEXT,
        minsize(sizeof(BANNER_TEXT) - 1, TERM_WIDTH)
    );
    gBannerPosition = TERM_WIDTH;
}

int main ( int argc, const char * const * const argv ) {
    initStars();
    initBanner();
    while (1) {
        clearScreen();
        animateStars();
        animateBanner();
        printScreen();
        sleepForMS(FRAME_DURATION);
    }
}

默认情况下,它希望您的终端为 80x25 个字符,但只需更改顶部的定义,您就可以使其适合任何终端尺寸。这些值必须正确,否则无法正确显示。它看起来是好是坏取决于您的终端能够以多快的速度刷新其内容。您可以通过调整FRAME_DURATION常数来稍微调整结果。代码在 macOS 上使用clang -o demo demo.c,在 Linux 上使用gcc -lm -o demo demo.c. 我也尝试让它与 Windows 兼容,但没有在 Windows 上进行测试。


推荐阅读