Ngôn ngữ C ++ được phát triên từ ngôn ngữ C. Có thể coi C++ là một cái tiến của C. Nó mang đầy đủ các đặc tính của C. Một chương trình viết bằng C có thể biên dịch được bằng trình biên dịch của C++. Ở những phiên bản đầu tiên, thực chất mã nguồn C++ đầu tiên được dịch sang mã nguồn C, rồi từ mã nguồn C tiếp tục được biên dịch tiếp. C++ là ngôn ngữ lập trình hướng đối tượng, do vậy nó có đầy đủ các tính chất của một ngôn ngữ lập trình hướng đối tượng: tính kế thừa, tính đóng kín, tính đa dạng. Nhưng C++ không phải là ngôn ngữ hướng đối tượng hoàn toàn mà là ngôn ngữ “đa hướng”. Vì C++ hỗ trợ cả lập trình hướng hành động và lập trình có cấu trúc với việc phân chia một bài toán thành các nhóm nhỏ có quan hệ với nhau, mỗi nhóm con đó là một đối tượng chứa các lệnh và dữ liệu riêng của nó. C++ đưa vào các khái niệm hàm ảo, quá tải hàm, quá tải toán tử cho phép tạo ra các kiểu dữ liệu trừu tượng, hỗ trợ thừa kế bội. Mục tiêu của C++ là tiếp cận những ý tưởng của phương pháp luận hướng đối tượng và trừu tượng dữ liệu. Các đặc tính của C++ cho phép người lập trình xây dựng những thư viện phần mềm có chất lượng cao phục vụ những chương trình lớn như các hệ soạn thảo, chương trình dịch, các hệ quản trị cơ sở dữ liệu, các hệ truyền thông…
Trang 1TRƯỜ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:
HÀ NỘI, 06/2018
Trang 2Ch ương trình chính 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 SetDirection(const CSize& sz);
void Move();
void Invalidate();
void 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)
{
Trang 3data->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()
{
Trang 4auto 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;
}
Trang 5Iterator& operator++() {
if (++colIndex == container->_cols) {
colIndex = 0;
rowIndex++;
}
return *this; }
bool operator!=(const Iterator& it) { return rowIndex != it.rowIndex || colIndex != it.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;
Trang 6Draw.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:
CPoint Location;
CSize Size;
Trang 7CRect() { }
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)
Trang 8COORD 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
Trang 9#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();
};
Trang 10#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);
}