Понять алгоритм Тетриса в консоли - C#
Формулировка задачи:
Уважаемые, помогите новичку! Разбираю игру Тетрис и не могу понять несколько моментов:
1. в классе Field есть методы проверки возможности сдвига фигуры вправо/влево. И я хоть убей, не могу понять их алгоритма((( насколько я поняла: мы берем координаты игрового поля и проверяем наличие фигуры в них. НО! К примеру у нас фигура Вертикальная линия (Line в позиции 2 или 4),мы проверяем возможность сдвига влево:
о чем здесь речь?
2. что дает нам этот цикл (в Main)?
Код:
for (int i = 0; i < 4; i++)
{
if (tetrisField[curY + i, curX] ==true|| curX == 0)
return false;
} for (int i = 0; i < 10 - f.level; i++) //количество итераций цикла имитирует скорость
{
System.Threading.Thread.Sleep(50);using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EventProject
{
delegate void Up();
delegate void Down();
delegate void Left();
delegate void Right();
class EventUp
{
// Объявляем событие
public event Up UpEvent;
// Используем метод для запуска события
public void UpUserEvent()
{
UpEvent();
}
}
class EventDown
{
// Объявляем событие
public event Down DownEvent;
// Используем метод для запуска события
public void DownUserEvent()
{
DownEvent();
}
}
class EventLeft
{
// Объявляем событие
public event Left LeftEvent;
// Используем метод для запуска события
public void LeftUserEvent()
{
LeftEvent();
}
}
class EventRight
{
// Объявляем событие
public event Right RightEvent;
// Используем метод для запуска события
public void RightUserEvent()
{
RightEvent();
}
}
public enum FigType { line, square, rightL, leftL, pyramide, leftZ, rightZ }; //перечисление возможных фигур
//класс фигура
class Figura
{
public bool[,] matrix = new bool[4, 4]; //матрица контейнер для размещения фигур
public FigType type; //тип фигуры
public int position; //положение фигуры
//стирание фигуры
public void Clear(bool[,] m)
{
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
m[i, j] = false;
}
//создание фигуры
public void Create(FigType figtype)
{
Clear(matrix); //стираем фигуру
this.type = figtype;
this.position = 1;
switch (figtype) //анализируем переданную в функцию фигуру
{
case FigType.line: //линия
{
for (int i = 0; i < 4; i++)
matrix[0, i] = true;
break;
}
case FigType.square: //квадрат
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
matrix[i, j] = true;
break;
}
case FigType.leftL:
{
for (int i = 0; i < 3; i++)
matrix[0, i] = true;
matrix[1, 2] = true;
break;
}
case FigType.rightL:
{
for (int i = 0; i < 3; i++)
matrix[0, i] = true;
matrix[1, 0] = true;
break;
}
case FigType.pyramide:
{
for (int i = 0; i < 3; i++)
matrix[1, i] = true;
matrix[0, 1] = true;
break;
}
case FigType.leftZ:
{
matrix[0, 0] = true; matrix[1, 0] = true;
matrix[1, 1] = true; matrix[2, 1] = true;
break;
}
case FigType.rightZ:
{
matrix[0, 1] = true; matrix[1, 0] = true;
matrix[1, 1] = true; matrix[2, 0] = true;
break;
}
}
}
//вращение фигуры
public void Rotate()
{
if (this.position == 4) //если текущая позиция =4
{
this.position = 1; //в начальное положение
}
this.position++; //меняем положение
switch (type)
{
case FigType.line: //если линия
{
//int k;
if (matrix[0, 0] == true)
{
Clear(matrix);
for (int k = 0; k < 4; k++)
matrix[k, 1] = true;
}
else
{
Clear(matrix);
for (int k = 0; k < 4; k++)
matrix[0, k] = true;
}
break;
}
case FigType.square: //если квадрат
{
return;
}
default: //остальные виды фигур (так как они зеркально похожи)
{
bool[,] tempFig = new bool[4, 4]; //создаем матрицу для временной фигуры
Clear(tempFig); //очищаем временную матрицу
for (int j = 3 - 1, c = 0; j >= 0; j--, c++) //указываем на какие клетки во временной матрице фигуры будут меняться клетки фигуры при вращении на одну позицию
for (int i = 0; i < 3; i++)
tempFig[c, i] = matrix[i, j];
Clear(matrix); //очищаем осовную матрицу (затираем фигуру )
for (int f = 0; f < 3; f++)
for (int d = 0; d < 3; d++)
matrix[f, d] = tempFig[f, d]; //рисуем новую фигуру (перевернутую)
break;
}
}
}
}
//класс игрового поля
class Field
{
public Figura fig = new Figura(); //фигура
int width; //ширина поля
int height; //высота поля
static bool[,] tetrisField; //игровое поле
int curY; //текущая координата у
int curX; //текущая координата х
public int scores; //очки за игру
public int level;
//конструктор
public Field(int w, int h)
{
this.width = w;
this.height = h;
tetrisField = new bool[height, width];
level = 0;
scores = 0;
}
//отрисовка поля с фигурой на нем
public void DrawField()
{
for (int i = 0; i < height - 1; i++)
{
for (int j = 1; j < width - 1; j++)
{
Console.CursorLeft = j;//устанавливаем курсор
Console.CursorTop = i;
if (tetrisField[i, j] == false) Console.WriteLine(" ");//заполняем поле пробелами
else Console.WriteLine("@"); //рисуем фигуру там, где true
}
Console.WriteLine();
}
Console.WriteLine("\n Level " + this.level);
Console.WriteLine("\n Scores " + this.scores);
}
//помечаем фигуру на игровом поле как true
public void Copy()
{
int x = curX; //временные переменные координаты для заполнения части поля
int y = curY;
for (int i = 0; i < 4; i++)
{
x = curX;
for (int j = 0; j < 4; j++)
{
if (fig.matrix[i, j] == true)
tetrisField[y, x] = true;
x++;
}
y++;
}
}
//создание новой фигуры
public void NewFig()
{
Random r = new Random();
curY = 0;
curX = 5;
FigType t = (FigType)r.Next(0, 7); //рандомим тип фигуры
fig.Create(t); //создаем эту фигуру
this.Copy(); //помечаем фигуру
}
//движение фигуры вниз
public void Move()
{
this.ClearPrevious(); //очищаем предыдущий шаг
curY++; //сдвгаем координату на один вниз
this.Copy();
this.DrawField();//отрисовыаем новое поле с фигурой
}
//стирание предыдущего шага
public void ClearPrevious()
{
int m = 0;
int n = 0;
for (int i = curY; i < curY + 4; i++)
{
for (int j = curX; j < curX + 4; j++)
{
if (fig.matrix[m, n] == true)
tetrisField[i, j] = false;
n++; //переходим на ячейку вправо
}
m++; //переходим на ячейку вниз
n = 0;
}
}
//проверка возможности вращения фигуры
public bool CheckRotation()
{
return false;
}Решение задачи: «Понять алгоритм Тетриса в консоли»
textual
Листинг программы
if (fig.position == 2 || fig.position == 4)
{
for (int i = 0; i < 4; i++)
{
if (tetrisField[curY + i, curX - 1]==true || curX == 1)
return false;
}
return true;
}