c - 蛇和梯子板 - 输出不打印出来
问题描述
我正在尝试使用 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 打印,因为它不允许您自由移动光标或清除之前打印的内容,因此您无法更新已打印到屏幕的内容. 不确定 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 上进行测试。
推荐阅读
- javascript - 地图功能不断重复输出
- discord.js - 我如何让机器人自聋?
- css - Django 模板中的动态内联 CSS 样式
- docker - 无法连接到 localhost 中的 Wordpress docker 容器
- javascript - 为什么我的事件处理函数未定义?
- php - 我如何遍历每日日期的多维数组并按月分组
- javascript - Fabricjs - 在画布上实现撤消/重做
- html - 如何使用拉伸链接引导类并在卡本身上保持 :hover 行为?
- teiid - Teiid QueryParser 不解析 SELECT TOP number|percent column_name(s)
- python - 在opencv-python中更改视频源时对图像的检测不佳