c - c程序的窗口大小调整影响元素位置
问题描述
我想在 c 中创建一个扫雷生成器,每当我运行程序时,要么窗口出现奇怪的形状,从而改变元素的位置以使其看起来不正确,或者我用来生成图块的函数生成不正确。我将如何解决这两个问题?我的代码在这里:
#include <windows.h> /* for HANDLE type, and console functions */
#include <stdio.h> /* standard input/output */
#include <stdlib.h> /* included for rand */
#define WIDTH 70
#define HEIGHT 35
#define BOMBS 20
HANDLE wHnd; /* write (output) handle */
HANDLE rHnd; /* read (input handle */
void SetGrid(int grid[WIDTH][HEIGHT])
{
int bomb[2] = {abs(rand() % WIDTH),
abs(rand() % HEIGHT)};
for (int i = 0; i < BOMBS; i++)
{
while (grid[bomb[0]][bomb[1]] < -1)
{
bomb[0] = abs(rand() % WIDTH);
bomb[1] = abs(rand() % HEIGHT);
}
grid[bomb[0]][bomb[1]] = -9;
grid[bomb[0]+1][bomb[1]+1]++;
grid[bomb[0]-1][bomb[1]-1]++;
grid[bomb[0]-1][bomb[1]+1]++;
grid[bomb[0]+1][bomb[1]-1]++;
grid[bomb[0]-1][bomb[1]]++;
grid[bomb[0]+1][bomb[1]]++;
grid[bomb[0]][bomb[1]-1]++;
grid[bomb[0]][bomb[1]+1]++;
}
}
int main(void)
{
srand(time(0));
SMALL_RECT windowSize = {0, 0, WIDTH - 1, HEIGHT - 1};
COORD bufferSize = {WIDTH, HEIGHT};
COORD characterBufferSize = {WIDTH, HEIGHT};
COORD characterPosition = {0, 0};
SMALL_RECT consoleWriteArea = {0, 0, WIDTH - 1, HEIGHT - 1};
CHAR_INFO consoleBuffer[WIDTH][HEIGHT];
wHnd = GetStdHandle(STD_OUTPUT_HANDLE);
rHnd = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleTitle("Our shiny new title!");
SetConsoleWindowInfo(wHnd, TRUE, &windowSize);
SetConsoleScreenBufferSize(wHnd, bufferSize);
int startGrid[WIDTH][HEIGHT] = {0};
SetGrid(startGrid);
for (int x = 0; x < WIDTH; ++x)
{
for (int y = 0; y < HEIGHT; ++y)
{
if(startGrid[x][y] > 0)
{
consoleBuffer[x][y].Char.AsciiChar = '0' + startGrid[x][y];
consoleBuffer[x][y].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
else
{
consoleBuffer[x][y].Char.AsciiChar = (unsigned char)219;
consoleBuffer[x][y].Attributes = (startGrid[x][y] < 0 ? FOREGROUND_RED : FOREGROUND_BLUE) | FOREGROUND_INTENSITY;
}
}
}
WriteConsoleOutputA(wHnd, consoleBuffer, characterBufferSize, characterPosition, &consoleWriteArea);
getchar();
}
解决方案
您需要处理几个边界问题。
- 四个角默认为-4
- 除了四个角,边框是-6(虽然你没用过)
- 重要:边界处的增加考虑是否超出边界。
这是代码:
#include <windows.h> /* for HANDLE type, and console functions */
#include <stdio.h> /* standard input/output */
#include <stdlib.h> /* included for rand */
#define WIDTH 30
#define HEIGHT 30
#define BOMBS 10
HANDLE wHnd; /* write (output) handle */
HANDLE rHnd; /* read (input handle */
int check(int a)
{
if (a == 0 || a == WIDTH - 1 || a == HEIGHT - 1)
{
return 1;
}
else
{
return 0;
}
}
void SetGrid(int grid[WIDTH][HEIGHT])
{
int bomb[2] = { abs(rand() % WIDTH),
abs(rand() % HEIGHT) };
char t[100];
for (int i = 0; i < BOMBS; i++)
{
while (grid[bomb[0]][bomb[1]] < -1)
{
bomb[0] = abs(rand() % WIDTH);
bomb[1] = abs(rand() % HEIGHT);
}
grid[bomb[0]][bomb[1]] = -9;
if (check(bomb[0]) || check(bomb[1])) grid[bomb[0]][bomb[1]] = -6;
if (check(bomb[0]) && check(bomb[1])) grid[bomb[0]][bomb[1]] = -4;
if (bomb[0] + 1 <= WIDTH - 1 && bomb[1] + 1 <= HEIGHT - 1)
{
grid[bomb[0] + 1][bomb[1] + 1]++;
}
if (bomb[0] + 1 <= WIDTH - 1)
{
grid[bomb[0] + 1][bomb[1]]++;
}
if (bomb[1] + 1 <= HEIGHT - 1)
{
grid[bomb[0]][bomb[1] + 1]++;
}
if (bomb[0] - 1 >= 0 && bomb[1] + 1 <= HEIGHT - 1)
{
grid[bomb[0] - 1][bomb[1] + 1]++;
}
if (bomb[1] - 1 >= 0)
{
grid[bomb[0]][bomb[1] - 1]++;
}
if (bomb[1] - 1 >= 0 && bomb[0] + 1 <= WIDTH - 1)
{
grid[bomb[0] + 1][bomb[1] - 1]++;
}
if (bomb[0] - 1 >= 0 && bomb[1] - 1 >= 0)
{
grid[bomb[0] - 1][bomb[1] - 1]++;
}
if (bomb[0] - 1 >= 0)
{
grid[bomb[0] - 1][bomb[1]]++;
}
}
}
int main(void)
{
srand(time(0));
SMALL_RECT windowSize = { 0, 0, WIDTH - 1, HEIGHT - 1 };
COORD bufferSize = { WIDTH, HEIGHT };
COORD characterBufferSize = { WIDTH, HEIGHT };
COORD characterPosition = { 0, 0 };
SMALL_RECT consoleWriteArea = { 0, 0, WIDTH - 1, HEIGHT - 1 };
CHAR_INFO consoleBuffer[WIDTH][HEIGHT];
wHnd = GetStdHandle(STD_OUTPUT_HANDLE);
rHnd = GetStdHandle(STD_INPUT_HANDLE);
SetConsoleTitle("Our shiny new title!");
SetConsoleWindowInfo(wHnd, TRUE, &windowSize);
SetConsoleScreenBufferSize(wHnd, bufferSize);
int startGrid[WIDTH][HEIGHT] = { 0 };
SetGrid(startGrid);
for (int x = 0; x < WIDTH; ++x)
{
for (int y = 0; y < HEIGHT; ++y)
{
if (startGrid[x][y] > 0)
{
consoleBuffer[x][y].Char.AsciiChar = '0' + startGrid[x][y];
consoleBuffer[x][y].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
}
else
{
consoleBuffer[x][y].Char.AsciiChar = (unsigned char)111;
consoleBuffer[x][y].Attributes = (startGrid[x][y] < 0 ? FOREGROUND_RED : FOREGROUND_BLUE) | FOREGROUND_INTENSITY;
}
}
}
WriteConsoleOutputA(wHnd, consoleBuffer, characterBufferSize, characterPosition, &consoleWriteArea);
printf("\n\n");
getchar();
}
推荐阅读
- amazon-web-services - 将 SG 附加到 EC2 实例所需的最低 IAM 权限?
- multithreading - 使在一个线程上运行的窗口模态到在另一个线程上运行的主窗口
- javascript - Require 在 Webpack 中没有定义 %
- html - 具有特殊字符的 Richsnippet 不是有效的 HTML
- python - Python selenium iframe 点击按钮
- module - 当一个函数调用自身内部的另一个函数时,它是什么类型的模块耦合?
- python - 删除 Line2D 对象后 Matplotlib 图不更新?
- sql - 在 Google BigQuery SQL 中,如何连接同一个人的字符串行?
- python - 从 wunderground 抓取历史天气数据
- c# - 隐式流向 url 添加哈希前缀