Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as C++ by NguyenVietNamSon ( 5 years ago )
#include <iostream>
#include <Windows.h>
#include <time.h>
#include <conio.h>
#include <thread>
#include <vector>
using namespace std;
#pragma warning(disable: 4996)
//Hằng số
#define MAX_CAR 3
#define MAX_CAR_LENGTH 5
#define MAX_SPEED 3
//Biến toàn cục
POINT** X; //Mảng chứa MAX_CAR xe
POINT Y; // Đại diện người qua đường
vector<POINT> Y_Success; // Mảng chứa các vị trí người đã qua đường thành công
int cnt = 0;//Biến hỗ trợ trong quá trình tăng tốc độ xe di chuyển
int MOVING;//Biến xác định hướng di chuyển của người
int SPEED;// Tốc độ xe chạy (xem như level)
int HEIGH_CONSOLE = 2 + MAX_CAR + 1, WIDTH_CONSOLE = 100;// Độ rộng và độ cao của màn hình console
bool STATE; // Trạng thái sống/chết của người qua đường
//int TIME_PAUSE = 20;
//int STATE_PAUSE = 0;
void DrawSticker(const POINT& p, const char* s);
void FixConsoleWindow() {
HWND consoleWindow = GetConsoleWindow();
LONG style = GetWindowLong(consoleWindow, GWL_STYLE);
style = style & ~(WS_MAXIMIZEBOX) & ~(WS_THICKFRAME);
SetWindowLong(consoleWindow, GWL_STYLE, style);
}
// Hàm tô màu.
void textcolor(int x)
{
HANDLE mau;
mau = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(mau, x);
}
void GotoXY(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
//Hàm khởi tạo dữ liệu mặc định ban đầu
void ResetData() {
Y_Success.clear();
MOVING = 'D'; // Ban đầu cho người di chuyển sang phải
SPEED = 1; // Tốc độ lúc đầu
// Vị trí lúc đầu của người
//Y = { WIDTH_CONSOLE / 2, 2 + MAX_CAR };
Y.x = WIDTH_CONSOLE / 2;
Y.y = 2 + MAX_CAR;
// Tạo mảng xe chạy
if (X == NULL) {
X = new POINT * [MAX_CAR];
for (int i = 0; i < MAX_CAR; i++)
X[i] = new POINT[MAX_CAR_LENGTH];
for (int i = 0; i < MAX_CAR; i++)
{
int temp = (rand() % (WIDTH_CONSOLE - MAX_CAR_LENGTH) / 8) + 1;
for (int j = 0; j < MAX_CAR_LENGTH; j++)
{
X[i][j].x = temp + j * 8;
X[i][j].y = 2 + i;
}
}
}
}
void DrawBoard(int x, int y, int width, int height, int curPosX = 0, int curPosY = 0)
{
GotoXY(x, y); cout << 'X';
for (int i = 1; i < width; i++)cout << 'X';
cout << 'X';
GotoXY(x, height + y); cout << 'X';
for (int i = 1; i < width; i++)cout << 'X';
cout << 'X';
for (int i = y + 1; i < height + y; i++)
{
GotoXY(x, i); cout << 'X';
GotoXY(x + width, i); cout << 'X';
}
GotoXY(curPosX, curPosY);
}
void StartGame() {
system("cls");
ResetData(); // Khởi tạo dữ liệu gốc
DrawBoard(0, 0, WIDTH_CONSOLE, HEIGH_CONSOLE); // Vẽ màn hình game
STATE = true;//Bắt đầu cho Thread chạy
}
//Hàm dọn dẹp tài nguyên
void GabageCollect()
{
for (int i = 0; i < MAX_CAR; i++)
{
delete[] X[i];
}
delete[] X;
}
//Hàm thoát game
void ExitGame(HANDLE t) {
TerminateThread(t, 0);
GabageCollect();
system("cls");
}
//Hàm dừng game
void PauseGame(HANDLE t) {
SuspendThread(t);
}
// Hàm xử lý khi người hiện tại đụng người đã về trước đó
void ProcessDeadMeeting()
{
STATE = 0;
GotoXY(0, HEIGH_CONSOLE + 2);
printf(" ");
GotoXY(0, HEIGH_CONSOLE + 2);
printf("Dead is meeting, type y to continue or anykey to exit");
}
//Hàm xử lý khi người đụng xe
void ProcessDead() {
// chạy qua 15 mã màu và liên tục xóa rồi vẽ lại chữ "Y" với mỗi lần sẽ có mã màu khác => tạo hiệu ứng nhấp nháy
for (int k = 1; k <= 15; ++k)
{
DrawSticker(Y, " ");
textcolor(k);
DrawSticker(Y, "Y");
Sleep(200);
}
textcolor(7); // reset trở lại màu bình thường
GotoXY(0, HEIGH_CONSOLE + 2);
printf(" ");
GotoXY(0, HEIGH_CONSOLE + 2);
printf("Dead, type y to continue or anykey to exit");
STATE = 0;
}
//Hàm xử lý khi người băng qua đường thành công
void ProcessFinish(POINT& p) {
Y_Success.push_back(p);
SPEED == MAX_SPEED ? SPEED = 1 : SPEED++;
//p = { WIDTH_CONSOLE / 2, 2 + MAX_CAR }; // Vị trí lúc đầu của người
p.x = WIDTH_CONSOLE / 2;
p.y = 2 + MAX_CAR;
MOVING = 'D'; // Ban đầu cho người di chuyển sang phải
//STATE_PAUSE = TIME_PAUSE;
if(SPEED == 1)
{
StartGame();
}
}
//Hàm vẽ các toa xe
void DrawCars(const char* s)
{
for (int i = 0; i < MAX_CAR; i++) {
for (int j = 0; j < MAX_CAR_LENGTH; j++)
{
GotoXY(X[i][j].x, X[i][j].y);
printf(s);
}
}
}
//Hàm vẽ người qua đường
void DrawSticker(const POINT& p, const char* s) {
GotoXY(p.x, p.y);
printf(s);
}
//Hàm kiểm tra xem người qua đường có đụng xe không
bool IsImpact(const POINT& p, int d)
{
if (d == 1 || d == 2 + MAX_CAR)return false;
for (int i = 0; i < MAX_CAR_LENGTH; i++)
{
if (p.x == X[d - 2][i].x && p.y == X[d - 2][i].y) return true;
}
return false;
}
// Hàm kiểm tra xem người qua đường thành công có bị đụng với những vị trí đã qua thành công trước đó không?
bool IsMeeting(const POINT& p)
{
if (p.y != 1)
return false;
// Nếu p.y == 1 thì bắt đầu xét vòng lặp xem vị trí x của người hiện tại có bị trùng với bất kỳ vị trí x nào của người trước đó đã qua thành công không?
for (int i = 0; i < Y_Success.size(); ++i)
{
if (Y_Success[i].x == p.x)
return true;
}
return false;
}
void MoveCars() {
// trái sang phải
srand(time(0));
for (int i = 1; i < MAX_CAR; i += 2)
{
int tamdung = rand() % 10;
if(tamdung == 5)
continue;
//cnt = 0;
//do {
//cnt++;
/*for (int j = 0; j < MAX_CAR_LENGTH - 1; j++) {
X[i][j] = X[i][j + 1];
}
X[i][MAX_CAR_LENGTH - 1].x */
////X[i][MAX_CAR_LENGTH - 1].x + 5 >= WIDTH_CONSOLE ? X[i][MAX_CAR_LENGTH -
// //1].x = (X[i][MAX_CAR_LENGTH - 1].x + 5) % WIDTH_CONSOLE : X[i][MAX_CAR_LENGTH - 1].x += 5; // Kiểm tra xem xe có đụng màn hình không
//if(X[i][MAX_CAR_LENGTH - 1].x + 1 >= WIDTH_CONSOLE)
// X[i][MAX_CAR_LENGTH - 1].x = 1;
//else
// X[i][MAX_CAR_LENGTH - 1].x++;
for(int j = 0; j < MAX_CAR_LENGTH; ++j)
{
GotoXY(X[i][j].x, X[i][j].y);
printf(" ");
X[i][j].x += SPEED;
if(X[i][j].x >= WIDTH_CONSOLE)
X[i][j].x = 1;
GotoXY(X[i][j].x, X[i][j].y);
printf("*");
//if(X[i][j].x >= WIDTH_CONSOLE)
//X[i][j].x = 1;
}
//} while (cnt < SPEED);
}
// phải sang trái
for (int i = 0; i < MAX_CAR; i += 2)
{
int tamdung = rand() % 10;
if(tamdung == 5)
continue;
//cnt = 0;
//do {
//cnt++;
/*for (int j = MAX_CAR_LENGTH - 1; j > 0; j--)
{
X[i][j] = X[i][j - 1];
}*/
////X[i][0].x - 5 <= 0 ? X[i][0].x : X[i][0].x -= 5;// Kiểm tra xem xe có đụng màn hình không
//if(X[i][0].x - 1 <= 0)
// X[i][0].x = WIDTH_CONSOLE - 1;
//else
// X[i][0].x--;
for(int j = 0; j < MAX_CAR_LENGTH; ++j)
{
GotoXY(X[i][j].x, X[i][j].y);
printf(" ");
X[i][j].x -= SPEED;
if(X[i][j].x <= 0)
X[i][j].x = WIDTH_CONSOLE - 1;
GotoXY(X[i][j].x, X[i][j].y);
printf("*");
//if(X[i][j].x <= 0)
//X[i][j].x = WIDTH_CONSOLE;
}
//} while (cnt < SPEED);
}
}
// Hàm xóa xe (xóa có nghĩa là không vẽ)
void EraseCars()
{
// phải sang trái => xóa thằng cuối
//for (int i = 0; i < MAX_CAR; i += 2) {
// //cnt = 0;
// //do {
// GotoXY(X[i][MAX_CAR_LENGTH - 1].x, X[i][MAX_CAR_LENGTH - 1].y);
// printf(" ");
// //cnt++;
// //} while (cnt < SPEED);
//}
//// trái sang phải => xóa thằng đầu
//for (int i = 1; i < MAX_CAR; i += 2) {
// //cnt = 0;
// //do {
// GotoXY(X[i][0].x, X[i][0].y);
// printf(" ");
// //cnt++;
// //} while (cnt < SPEED);
//}
}
void MoveRight() {
if (Y.x < WIDTH_CONSOLE - 1)
{
DrawSticker(Y, " ");
Y.x++;
DrawSticker(Y, "Y");
}
}
void MoveLeft() {
if (Y.x > 1) {
DrawSticker(Y, " ");
Y.x--;
DrawSticker(Y, "Y");
}
}
void MoveDown() {
if (Y.y < HEIGH_CONSOLE - 1)
{
DrawSticker(Y, " ");
Y.y++;
DrawSticker(Y, "Y");
}
}
void MoveUp() {
if (Y.y > 1) {
DrawSticker(Y, " ");
Y.y--;
DrawSticker(Y, "Y");
}
}
// Đến 1 thời điểm ngẫu nhiên hàm này sẽ được gọi tự động
void TamDungCacToaXe()
{
// tạm dừng số lượng ngẫu nhiên số lượng các toa xe (có thể nhiều hơn 1)
// các toa xe cụ thể được tạm dừng cũng ngẫu nhiên
// tạm dừng thời gian ngẫu nhiên (trong khoảng từ 3 đến 6 giây)
/*for(int i = 0; i < MAX_CAR; ++i)
{
}*/
}
void SubThread()
{
while (1) {
if (STATE) //Nếu người vẫn còn sống
{
switch (MOVING) //Kiểm tra biến moving
{
case 'A':
MoveLeft();
break;
case 'D':
MoveRight();
break;
case 'W':
MoveUp();
break;
case 'S':
MoveDown();
break;
}
MOVING = ' ';// Tạm khóa không cho di chuyển, chờ nhận phím từ hàm main
//if (STATE_PAUSE <= 0)
{
GotoXY(0, HEIGH_CONSOLE + 2);
printf(" ");
//EraseCars();
MoveCars();
//DrawCars(".");
}
if (IsImpact(Y, Y.y))
{
ProcessDead(); // Kiểm tra xe có đụng không
//STATE_PAUSE = -1;
}
// Kiểm tra bị đụng với những người đã về đích trước đó
if (IsMeeting(Y))
{
ProcessDeadMeeting();
//STATE_PAUSE = -1;
}
if (Y.y == 1 && STATE == 1) // Phải có thêm kiểm tra state == 1 (tức là người còn sống) bởi nếu không thì trường hợp giả sử trong thời gian tạm dừng các toa xe người đó bị đụng vào người đã về trước đó thì lúc này tuy mình xét in ra câu thông báo bị đụng nhau nhưng vì lúc này P.y của người hiện tại là 1 (đích đến) nên nó lại thỏa điều kiện này và vì thế lại gọi hàm ProcessFinish và trong hàm thì cập nhật biến STATE_PAUSE = TIME_PAUSE và như thế nó lại xét thấy STATE_PAUSE >= 0 mà thỏa và in ra câu các toa xe đang tạm dừng ... Nên ở đây phải kèm thêm điều kiện là về đích và trạng thái người đó phải đang còn sống thì mới tính
ProcessFinish(Y); // Kiểm tra xem về đích chưa
/*if (STATE_PAUSE >= 0)
{
GotoXY(0, HEIGH_CONSOLE + 2);
printf(" ");
GotoXY(0, HEIGH_CONSOLE + 2);
printf("Tranh thu qua duong nao. Cac xe se tiep tuc chay trong: %d", STATE_PAUSE);
STATE_PAUSE--;
}*/
Sleep(50);//Hàm ngủ theo tốc độ SPEED
}
}
}
void main()
{
int temp;
FixConsoleWindow();
srand(time(NULL));
StartGame();
thread t1(SubThread);
while (1)
{
temp = toupper(getch());
if (STATE == 1)
{
if (temp == 27) {
ExitGame(t1.native_handle());
//return;
exit(0);
}
else if (temp == 'P') {
PauseGame(t1.native_handle());
}
else {
ResumeThread((HANDLE)t1.native_handle());
if (temp == 'D' || temp == 'A' || temp == 'W' || temp == 'S')
{
MOVING = temp;
}
}
}
else
{
if (temp == 'Y') StartGame();
else {
ExitGame(t1.native_handle());
//return;
exit(0);
}
}
}
getch();
}
Revise this Paste