using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Threading;
namespace TetrisPlugin
{
public class TetrisSquare
{
public int X { get; set; }
public int Y { get; set; }
public string Color { get; set; }
public TetrisSquare(int x = 0, int y = 0, string color = "gray")
{
X = x;
Y = y;
Color = color;
}
public Point2d GetCord()
{
return new Point2d(X, Y);
}
public void SetColor(string color)
{
Color = color;
}
public string GetColor()
{
return Color;
}
public Point2d GetMovedCord(int direction)
{
int x = X;
int y = Y;
switch (direction)
{
case TetrisGame.MOVE_LEFT:
x--;
break;
case TetrisGame.MOVE_RIGHT:
x++;
break;
case TetrisGame.MOVE_DOWN:
y++;
break;
}
return new Point2d(x, y);
}
}
public class TetrisField
{
private readonly int width = 10; // Fix width and height
private readonly int height = 20;
private TetrisSquare[,] squares;
public TetrisField()
{
squares = new TetrisSquare[height, width];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
squares[y, x] = new TetrisSquare(x, y, "gray");
}
}
}
public int GetWidth()
{
return width;
}
public int GetHeight()
{
return height;
}
public TetrisSquare GetSquare(int x, int y)
{
return squares[y, x];
}
public bool JudgeGameOver(TetrisBlock block)
{
HashSet<Point2d> noEmptyCord = new HashSet<Point2d>();
HashSet<Point2d> blockCord = new HashSet<Point2d>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() != "gray")
noEmptyCord.Add(new Point2d(x, y));
}
}
foreach (TetrisSquare square in block.GetSquares())
{
Point2d cord = square.GetCord();
blockCord.Add(cord);
}
blockCord.IntersectWith(noEmptyCord);
return blockCord.Count > 0;
}
public bool JudgeCanMove(TetrisBlock block, int direction)
{
HashSet<Point2d> noEmptyCord = new HashSet<Point2d>();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() != "gray")
noEmptyCord.Add(new Point2d(x, y));
}
}
HashSet<Point2d> moveBlockCord = new HashSet<Point2d>();
foreach (TetrisSquare square in block.GetSquares())
{
Point2d cord = square.GetMovedCord(direction);
moveBlockCord.Add(cord);
if (cord.X < 0 || cord.X >= width || cord.Y < 0 || cord.Y >= height)
return false;
}
moveBlockCord.IntersectWith(noEmptyCord);
return moveBlockCord.Count == 0;
}
public void FixBlock(TetrisBlock block)
{
foreach (TetrisSquare square in block.GetSquares())
{
int x = (int)square.GetCord().X;
int y = (int)square.GetCord().Y;
string color = square.GetColor();
squares[y, x].SetColor(color);
}
}
public void DeleteLine()
{
for (int y = height - 1; y >= 0; y--)
{
bool isFull = true;
for (int x = 0; x < width; x++)
{
if (squares[y, x].GetColor() == "gray")
{
isFull = false;
break;
}
}
if (isFull)
{
for (int yy = y; yy > 0; yy--)
{
for (int x = 0; x < width; x++)
{
squares[yy, x].SetColor(squares[yy - 1, x].GetColor());
}
}
for (int x = 0; x < width; x++)
{
squares[0, x].SetColor("gray");
}
y++;
}
}
}
}
public class TetrisBlock
{
private List<TetrisSquare> squares = new List<TetrisSquare>();
public TetrisBlock()
{
int blockType = new Random().Next(1, 5);
string color;
List<Point2d> cords = new List<Point2d>();
switch (blockType)
{
case 1:
color = "red";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2, 2));
cords.Add(new Point2d(10 / 2, 3));
break;
case 2:
color = "blue";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2 - 1, 1));
break;
case 3:
color = "green";
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2, 1));
cords.Add(new Point2d(10 / 2, 2));
break;
case 4:
color = "orange";
cords.Add(new Point2d(10 / 2, 0));
cords.Add(new Point2d(10 / 2 - 1, 0));
cords.Add(new Point2d(10 / 2 - 1, 1));
cords.Add(new Point2d(10 / 2 - 1, 2));
break;
default:
color = "gray";
break;
}
foreach (Point2d cord in cords)
{
squares.Add(new TetrisSquare((int)cord.X, (int)cord.Y, color));
}
}
public List<TetrisSquare> GetSquares()
{
return squares;
}
public void Move(int direction)
{
foreach (TetrisSquare square in squares)
{
Point2d movedCord = square.GetMovedCord(direction);
square.X = (int)movedCord.X;
square.Y = (int)movedCord.Y;
}
}
}
public class TetrisGame
{
private TetrisField field;
private TetrisBlock block;
private TetrisCanvas canvas;
public const int MOVE_LEFT = 0;
public const int MOVE_RIGHT = 1;
public const int MOVE_DOWN = 2;
public TetrisGame(TetrisCanvas canvas, TetrisField field, TetrisBlock block)
{
this.canvas = canvas;
this.field = field;
this.block = block;
}
public void Start(Action endFunc)
{
field = new TetrisField();
block = null;
canvas.Update(field, block);
}
public void NewBlock()
{
block = new TetrisBlock();
if (field.JudgeGameOver(block))
{
Console.WriteLine("GAMEOVER");
}
canvas.Update(field, block);
}
public void MoveBlock(int direction)
{
if (field.JudgeCanMove(block, direction))
{
block.Move(direction);
canvas.Update(field, block);
}
else
{
if (direction == MOVE_DOWN)
{
field.FixBlock(block);
field.DeleteLine();
NewBlock();
}
}
}
}
public class TetrisCanvas
{
private TetrisField beforeField;
private TetrisField field;
private readonly int BLOCK_SIZE = 25;
private readonly int FIELD_WIDTH = 10;
private readonly int FIELD_HEIGHT = 20;
public TetrisCanvas(TetrisField field)
{
this.field = field;
beforeField = field;
}
public void Update(TetrisField field, TetrisBlock block)
{
beforeField = field;
// Update canvas with new field and block
}
}
public class TetrisCommands
{
[CommandMethod("TETRIS")]
public void TetrisGame()
{
TetrisField field = new TetrisField();
TetrisBlock block = null;
TetrisCanvas canvas = new TetrisCanvas(field);
TetrisGame game = new TetrisGame(canvas, field, block);
game.Start(null); // You can pass a function to handle end game scenario
while (true)
{
// Get user input, for example through AutoCAD commands or UI buttons
// Depending on input, call game.MoveBlock(direction) with appropriate direction
}
}
}
}
プログラムを実行してみたが、エラーは出なかった。しかしAutoCADでTETRISとコマンドを入れたらそれっきりウンともスンとも言わなくなってしまった。