[已关闭]第一个在C++中的应用程序

gdrx4gfi  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(82)

已关闭。此问题为opinion-based。目前不接受回答。
**要改进此问题吗?**更新此问题,以便editing this post可以使用事实和引文来回答。

十年前就关门了。
Improve this question
我只是想问你一件事。我不指望你给我任何代码。我想做一个蛇游戏。我的想法是制作一个数组,用GetAsyncKeyState()函数控制蛇。我还没有决定如何移动蛇,但我正在考虑使用链表将蛇的身体坐标保存在数组中的想法。
我有两个问题:1.你喜欢我使用链表的想法吗?2.我需要以某种方式清除控制台并重新输出表。但如果我使用
system(“CLS”)
,屏幕会 Flink 。有没有更好的方法可以不 Flink 地清除控制台?
任何其他想法将不胜感激:)
下面是我的代码。

#include<iostream>
#include<windows.h>
using namespace std;
int matrix[20][40];
void FillMatrix()
    {
        for(int i = 0; i < 20; i++)
            for(int j = 0; j < 40; j++)
                matrix[i][j] = 0;
    }
void Show()
    {
        COORD pos = {0, 0};
        SetConsoleCursorPosition(cout, pos);
        for(int i = 0; i < 20; i++)
            {
                for(int j = 0; j < 40; j++)
                    {
                        if(i == 0 || j == 0 || i == 19 || j == 39) cout << "#";
                        else if(matrix[i][j] == 0) cout << " ";
                        else cout << ".";
                    }
                cout << endl;
            }
    }
void Change(int i, int j)
    {
        matrix[i][j] = 1;
    }
int main()
    {
        FillMatrix();
        int x, y;
        x = 4;
        y = 4;
        while(!GetAsyncKeyState(VK_ESCAPE))
            {
                Sleep(100);
                //system("cls");
                if(GetAsyncKeyState(VK_LEFT)) 
                    {
                        y = y-1;
                        Change(x, y);
                    }
                else 
                    if(GetAsyncKeyState(VK_UP)) 
                        {
                            x = x-1;
                            Change(x, y);
                        }
                else 
                    if(GetAsyncKeyState(VK_RIGHT)) 
                        {
                            y = y+1;
                            Change(x, y);
                        }
                else 
                    if(GetAsyncKeyState(VK_DOWN)) 
                        {
                            x = x+1;
                            Change(x, y);
                        }
                Show();
            }
        system("pause");
        return 0;
    }

字符串

xzlaal3s

xzlaal3s1#

使用链表几乎总是一个糟糕的主意。在这种情况下,似乎没有理由甚至考虑使用一个链表。使用链表的主要原因是当你需要在列表中间插入或删除项目时(并且,为了获得更多,已经有指向列表中需要进行插入/删除的特定位置的东西)。
因为你显然使用的是Win32,所以我根本不会清除屏幕,而是使用WriteConsoleOutput将新的输出写入屏幕,删除之前的任何内容。
虽然这不是一个蛇游戏 * 本身 *,这里的代码实现了约翰康威的生命游戏使用WriteConsoleOutput来产生屏幕输出。它还包括一个ClrScr函数来清除屏幕,如果你决定你真的 * 必须 * 这样做(但你可能不会)。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <io.h>

#define     ROWS        50
#define     COLS        80

// The total number of generations is really double this number.
int generations = 1000;

int civ1[ROWS+2][COLS+2], civ2[ROWS+2][COLS+2];

CHAR_INFO disp[ROWS][COLS];
HANDLE console;
COORD size = { COLS, ROWS };
COORD src = { 0, 0};
SMALL_RECT  dest = { 0, 0, COLS, ROWS };

void ClrScrn(char attrib) {
    COORD pos = { 0, 0};
    DWORD written;
    unsigned size;

    size = ROWS * COLS;

    FillConsoleOutputCharacter(console, ' ', size, pos, &written);
    FillConsoleOutputAttribute(console, attrib, size, pos, &written);
    SetConsoleCursorPosition(console, pos);
}

void fill_edges(int civ1[ROWS+2][COLS+2]) {
    int i, j;

    for (i=1; i<=ROWS; ++i) {
        civ1[i][0] = civ1[i][COLS];
        civ1[i][COLS+1] = civ1[i][1];
    }
    for (j=1; j<=COLS; ++j) {
        civ1[0][j] = civ1[ROWS][j];
        civ1[ROWS+1][j] = civ1[1][j];
    }
    civ1[0][0] = civ1[ROWS][COLS];
    civ1[ROWS+1][COLS+1] = civ1[1][1];
    civ1[0][COLS+1] = civ1[ROWS][1];
    civ1[ROWS+1][0] = civ1[1][COLS];
}

void update_generation(int old_gen[ROWS+2][COLS+2],
                        int new_gen[ROWS+2][COLS+2])
{
    int i, j, count;

    for (i = 1; i <= ROWS; ++i)
    {
        for (j = 1; j <= COLS; ++j)
        {
            count = old_gen[i - 1][j - 1] +
                old_gen[i - 1][j] +
                old_gen[i - 1][j + 1] +
                old_gen[i][j - 1] +
                old_gen[i][j + 1] +
                old_gen[i + 1][j - 1] +
                old_gen[i + 1][j] +
                old_gen[i + 1][j + 1];

            switch(count)
            {
            case 2:
                new_gen[i][j] = old_gen[i][j];
                break;

            case 3:
                new_gen[i][j] = 1;
                disp[i-1][j-1].Char.AsciiChar = '*';
                break;
            default:
                new_gen[i][j] = 0;
                disp[i-1][j-1].Char.AsciiChar = ' ';
                break;
            }
        }
    }
    WriteConsoleOutput(console, (CHAR_INFO *)disp, size, src, &dest);
    fill_edges(new_gen);
}

void initialize(void)
{
    int i, j;

    ClrScrn(0x71);
    srand(((unsigned int)time(NULL))|1);

    for (i = 1; i <= ROWS; ++i)
    {
        for (j = 1; j <= COLS; ++j)
        {
            civ1[i][j] = (int)(((__int64)rand()*2)/RAND_MAX);
            disp[i-1][j-1].Char.AsciiChar = civ1[i][j] ? '*' : ' ';
            disp[i-1][j-1].Attributes = 0x71;
        }
    }
    WriteConsoleOutput(console, (CHAR_INFO *)disp, size, src, &dest);
    fill_edges(civ1);
}

int main(int argc, char **argv) {

    int i;

    if ( argc != 1)
        generations = atoi(argv[1]);

    console = GetStdHandle(STD_OUTPUT_HANDLE);
    initialize();
    for (i = 0; i <generations; ++i)
    {
        update_generation(civ1, civ2);
        update_generation(civ2, civ1);
    }
    return EXIT_SUCCESS;
}

字符串

pengsaosao

pengsaosao2#

除非你能用一些合理化的方法来证明,否则听起来你选择了链表,因为你以前听过这个名字。
至于屏幕 Flink ,终端不会双缓冲,所以这就是它的方式,直到你使用像ncurses这样的库来移动光标,而不是反复清理屏幕,从头开始。

相关问题