TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN ĐIỆN TỬ - VIỄN THÔNG
BÀI TẬP C/C++
Đề tài:
GAME CỜ CARO
NHÓM SINH VIÊN:
2016xxxx
2016xxxx
Trần Văn Đông
Trần Văn Đông
HÀ NỘI, 06/2018
Trưởng nhóm
Chương trình chính
#pragma once
#include "../ClassRect/Draw.h"
#include "../ClassList/List.h"
#include "Cell.h"
class SnakePiece
{
public:
int Row, Col;
public:
SnakePiece(int row, int col)
: Row(row)
, Col(col)
{
}
SnakePiece operator+(const CSize& sz)
{
return SnakePiece(Row + sz.Height, Col + sz.Width);
}
};
class Snake : public List<SnakePiece>
{
BoardData* data;
int& At(const SnakePiece& p)
{
return (*data)(p.Row, p.Col);
}
CSize dir;
public:
Snake(BoardData *data, int x, int y, int length);
public:
bool Longer();
void
void
void
void
SetDirection(const CSize& sz);
Move();
Invalidate();
Invalidate(const SnakePiece& p);
int GetDataCellValue() { return dir.Height ? BoardData::Vert : BoardData::Horiz; }
void UpdateData(const SnakePiece& p)
{
data->SetAt(p.Row, p.Col, GetDataCellValue());
}
void UpdateData(const SnakePiece& p, int value)
{
data->SetAt(p.Row, p.Col, value);
}
public:
Iterator Head() { return Iterator(Last()); }
Iterator Tail() { return Iterator(First()); }
};
Snake::Snake(BoardData *data, int x, int y, int length)
: data(data)
{
dir = CSize(1, 0);
}
for (int i = 0; i < length; i++)
{
Append(SnakePiece(y, x));
}
void Snake::SetDirection(const CSize& sz)
{
if (dir.Height == sz.Height && dir.Width == sz.Width)
return;
auto p = *Head();
int v = At(p);
if (sz.Height < 0)
{
v = BoardData::Vert;
}
else
{
if (dir.Height < 0 && sz.Width)
v = BoardData::Horiz;
}
dir = sz;
UpdateData(p, v);
}
bool Snake::Longer()
{
auto p = *Head();
auto q = p + dir;
if (q.Row < 0 || q.Row >= data->GetRows())
throw(1);
if (q.Col < 0 || q.Col >= data->GetColumns())
throw(1);
int v = At(q);
if (v == BoardData::Horiz || v == BoardData::Vert)
throw(1);
Append(q);
UpdateData(q);
return v != BoardData::Empty;
}
void Snake::Move()
{
auto p = *Head();
if (!this->Longer())
{
p = *Tail();
RemoveFirst();
UpdateData(p, BoardData::Empty);
//ClearPiece(p);
}
UpdateData(*Head());
}
Matrix.h
#pragma once
template <class T>
class Matrix
{
T** _data;
int _rows, _cols;
void createData(int rows, int cols);
void deleteData();
void copyData(const T** src);
public:
Matrix() : _data(0) { }
Matrix(int rows, int cols = 0) { this->createData(rows, cols == 0 ? rows : cols); }
Matrix(const Matrix& M)
{
this->createData(M._rows, M._cols);
this->copyData(M._data);
}
~Matrix() { this->deleteData(); }
public:
void Fill(const T& value);
int GetRows() const { return _rows; }
int GetColumns() const { return _cols; }
T* operator[](int i) { return _data[i]; }
T& operator()(int i, int j) { return _data[i][j]; }
public:
class Iterator
{
int rowIndex, colIndex;
Matrix<T>* container;
public:
Iterator(Matrix& container, int i, int j) : rowIndex(i), colIndex(j)
{
this->container = &container;
}
Iterator& operator++()
{
if (++colIndex == container->_cols)
{
colIndex = 0;
rowIndex++;
}
return *this;
it.colIndex; }
}
bool operator!=(const Iterator& it) { return rowIndex != it.rowIndex || colIndex !=
T& operator *() { return container->_data[rowIndex][colIndex]; }
};
int Row() const { return rowIndex; }
int Column() const { return colIndex; }
void Offset(int row, int col)
{
rowIndex += row;
colIndex += col;
}
friend Iterator begin(Matrix& m) { return Iterator(m, 0, 0); }
friend Iterator end(Matrix& m) { return Iterator(m, m._rows, 0); }
};
template <class T> void Matrix<T>::createData(int rows, int cols)
{
_rows = rows;
_cols = cols;
_data = new T *[rows];
for (int i = 0; i < rows; i++)
_data[i] = new T[cols];
}
template <class T> void Matrix<T>::deleteData()
{
if (_data)
{
for (int i = 0; i < _rows; i++)
delete[] _data[i];
delete[] _data;
}
_data = 0;
}
template <class T> void Matrix<T>::copyData(const T** src)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = src[i][j];
}
template <class T> void Matrix<T>::Fill(const T& value)
{
for (int i = 0; i < _rows; i++)
for (int j = 0; j < _cols; j++)
_data[i][j] = value;
}
Draw.h
#pragma once
class CSize
{
public:
int Width, Height;
public:
CSize() { Width = Height = 0; }
CSize(int width, int height) : Width(width), Height(height) { }
public:
friend CSize operator+(const CSize& t, const CSize& s)
{
return CSize(t.Width + s.Width, t.Height + s.Height);
}
friend CSize& operator+=(CSize& t, const CSize& s)
{
t.Width += s.Width;
t.Height += s.Height;
return t;
}
};
class CPoint
{
public:
int X, Y;
public:
CPoint() { X = Y = 0; }
CPoint(int x, int y) : X(x), Y(y) { }
public:
CPoint& Offset(int x, int y)
{
X += x; Y += y;
return *this;
}
};
friend CPoint operator+(const CPoint& p, const CSize& s)
{
return CPoint(p.X + s.Width, p.Y + s.Height);
}
friend CPoint& operator+=(CPoint& p, const CSize& s)
{
p.X += s.Width;
p.Y += s.Height;
return p;
}
class CRect
{
public:
public:
CPoint Location;
CSize Size;
CRect() { }
CRect(int x1, int y1, int x2, int y2)
: Location(x1, y1)
, Size(x2 - x1 + 1, y2 - y1 + 1)
{
}
CRect(const CPoint& p1, const CPoint& p2)
: Location(p1)
, Size(p2.X - p1.X + 1, p2.Y - p1.Y + 1)
{
}
CRect(const CPoint& topLeft, const CSize& size)
: Location(topLeft)
, Size(size)
{
}
};
Screen.h
#pragma once
#include <Windows.h>
#include <iostream>
class Cursor
{
HANDLE handle;
public:
static Cursor Dedault;
public:
Cursor(HANDLE handle = 0)
{
if (handle == 0)
handle = GetStdHandle(STD_OUTPUT_HANDLE);
this->handle = handle;
}
void Show()
{
CONSOLE_CURSOR_INFO info;
GetConsoleCursorInfo(handle, &info);
}
info.bVisible = true;
SetConsoleCursorInfo(handle, &info);
void Hide()
{
CONSOLE_CURSOR_INFO info;
GetConsoleCursorInfo(handle, &info);
info.bVisible = false;
SetConsoleCursorInfo(handle, &info);
}
void MoveTo(int x, int y)
{
COORD coord;
coord.X = x;
coord.Y = y;
}
SetConsoleCursorPosition(handle, coord);
void Put(char c)
{
std::cout << c;
}
void Put(char *s)
{
std::cout << s;
}
};
void Put(int value)
{
std::cout << char(value);
}
Cell.h
#pragma once
#include "../Matrix/matrix.h"
#include "../Console/Board.h"
#include <iostream>
class BoardData : public Matrix<int>
{
CRect view;
public:
enum { Empty, Vert = 219, Horiz, Diamond = '*' };
public:
BoardData(const CRect& view)
: Matrix(view.Size.Height - 1, view.Size.Width - 1)
, view(view)
{
this->Fill(Empty);
}
void CreateRandomCell();
};
void SetAt(int i, int j, int value);
Cell.cpp
#include "Cell.h"
#include <iostream>
using namespace std;
void BoardData::SetAt(int i, int j, int value)
{
(*this)(i, j) = value;
int x = view.Location.X + 1 + j;
int y = view.Location.Y + 1 + i;
}
Cursor::Dedault.MoveTo(x, y);
std::cout << char(value);
void BoardData::CreateRandomCell()
{
int r = GetRows();
int c = GetColumns();
int pos = rand() % (r * c);
int i = pos / c;
int j = pos % c;
}
auto it = Iterator(*this, i, j);
auto e = end(*this);
while (it != e)
{
if (*it == Empty)
{
SetAt(it.Row(), it.Column(), Diamond);
break;
}
++it;
}
Board.h
#pragma once
#include "../Matrix/matrix.h"
#include "../ClassRect/Draw.h"
#include "../Console/Screen.h"
class Board : public CRect
{
void DrawFrame(int left, int middle, int right);
public:
};
Board(int x, int y, int rows, int cols)
: CRect(CPoint(x, y), CSize(cols, rows))
{
}
void Draw();
Board.cpp
#include "Board.h"
#include "../Console/Screen.h"
using namespace std;
#ifndef __CURSOR_DEFAULT
#define __CURSOR_DEFAULT
Cursor Cursor::Dedault;
#endif
void Board::Draw()
{
Cursor cursor;
int x = Location.X, y = Location.Y;
cursor.MoveTo(x, y);
this->DrawFrame(201, 205, 187);
for (int i = 0; i < Size.Height - 1; i++)
{
cursor.MoveTo(x, ++y);
this->DrawFrame(186, 32, 186);
}
cursor.MoveTo(x, y + 1);
this->DrawFrame(200, 205, 188);
}
void Board::DrawFrame(int left, int middle, int right)
{
cout << char(left);
for (int i = 0; i < Size.Width - 1; i++)
cout << char(middle);
cout << char(right);
}