Multithreading (Two)

Implemented to play music while playing Snake:

Cautions:

1. VS2017下async默认为launch:deffed,所以想要在future那句中启动线程需要在后面加上result1.get(),或者在future时,加上launch:async.
2. Once a thread is started, it will run until it finishes. 若想提前终止,需要在合适的时机return,若用result1._Abandon,线程会结束,但函数仍会继续运行,且有内存泄漏风险 (如果之前没释放的话).
3. 目前对线程的控制使用的是全局变量的方法,还没有涉及到同步化 (synchronization),如有需要请参见The C++ Standard Library 有关Mutex和Lock的部分。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <future>
#include <thread>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <exception>
#include <string>
#include <cstring>
#include <ctime>
#include <conio.h>
#include <windows.h>

#define b(a,b) Beep(a,b)
#define m 10001 

using namespace std;

const int a1 = 220;		//低音 由十二平均律计算得出 
const int a2 = 247;
const int a3 = 277;
const int a4 = 294;
const int a5 = 330;
const int a6 = 370;
const int a7 = 415;
const int b1 = 440;		//中音
const int b2 = 494;
const int b3 = 554;
const int b4 = 587;
const int b5 = 659;
const int b6 = 740;
const int b7 = 831;
const int c1 = 880;		//高音
const int c2 = 988;
const int c3 = 1109;
const int c4 = 1175;
const int c5 = 1319;
const int c6 = 1480;
const int c7 = 1661;
const int fx[] = { 0,-1,1, 0,0 };
const int fy[] = { 0, 0,0,-1,1 };
char c = 'w';
int px, py, flag;
int map[24][24], father[24][24];

int getint()
{
	int _b = 0; char _c;
	for (_c = getchar(); _c < '0' || _c > '9'; _c = getchar())
		;
	for (; _c >= '0' && _c <= '9'; _c = getchar())
	{
		_b *= 10;
		_b += _c - '0';
	}
	return _b;
}

struct point {
	int x;
	int y;
};
void clear()											//24 ↑ 25 ↓ 26 → 27 ← 
{
	memset(map, 0, sizeof(map));
	for (int i = 0; i <= 22; i++)
	{
		map[0][i] = 99;
		map[i][23] = 99;
		map[23][i + 1] = 99;
		map[i + 1][0] = 99;
	}
}
inline void print_first()
{
	system("cls");
	for (int i = 0; i <= 23; i++)
	{
		for (int j = 0; j <= 23; j++)
		{
			switch (map[i][j])
			{
			case 0:
			{
				printf("  ");
				break;
			}
			case 1:					//head
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_RED);
				printf("●");
				break;
			}
			case 2:					//body
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
				printf("■");
				break;
			}
			case 3:					//food
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
				printf("●");
				break;
			}
			case 99:
			{
				SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_BLUE);
				printf("■");
				break;
			}
			}
		}
		printf("\n");
	}
}

inline int ret(int _a, int _b)
{
	return _a * 25 + _b;
}

inline point rets(int num)
{
	point _a;
	_a.x = num / 25;
	_a.y = num % 25;
	return _a;
}

void gotoxy(int x, int y)
{
	COORD C;
	C.X = x * 2;
	C.Y = y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), C);
}

void print(int x, int y, int kp)
{
	gotoxy(x, y);
	switch (kp)
	{
	case 0:
	{
		printf("  ");
		break;
	}
	case 1:					//head
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_RED);
		printf("●");
		break;
	}
	case 2:					//body
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);
		printf("■");
		break;
	}
	case 3:					//food
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
		printf("●");
		break;
	}
	case 99:
	{
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BACKGROUND_INTENSITY | FOREGROUND_BLUE);
		printf("■");
		break;
	}
	}
}

inline void setfood()
{
	int l = 0;
	int r = 0;
	while (l == 0 || r == 0 || map[l][r] == 1 || map[l][r] == 2 || map[l][r] == 99)
	{
		l = rand() % 23;
		r = rand() % 23;
	}
	map[l][r] = 3;
	print(l, r, 3);
}

void music2()
{
	int pai = 360;
	int a[m] = { b3,b3,b5,b6,c1,c1,b6,b5,b5,b6,b5,0,			//茉莉花
		b3,b3,b5,b6,c1,c1,b6,b5,b5,b6,b5,0,
		b5,b5,b5,b3,b5,b6,b6,b5,0,
		b3,b2,b3,b5,b3,b2,b1,b1,b2,b1,0,
		b3,b2,b1,b3,b2,b3,b5,b6,c1,b5,0,
		b2,b3,b5,b2,b3,b1,a6,a5,0,
		a6,b1,b2,b3,b1,b2,b1,a6,a5,0 };
	int c22[m] = { 2,1,1,1,1,1,1,2,1,1,4,0,						//节奏
		2,1,1,1,1,1,1,2,1,1,4,0,
		2,2,2,1,1,2,2,4,0,
		2,1,1,2,1,1,2,1,1,4,0,
		1,1,1,1,3,1,2,1,1,4,0,
		2,1,1,1,1,1,1,4,0,
		2,2,3,1,1,1,1,1,6,0 };
	while (1)
	{
		for (int i = 0; i < 74; i++)
		{
			if (flag == 1 && a[i] == 0)							//播放到这一句完
				return;
			b(a[i], pai*c22[i]);
		}
	}
	system("cls");
}

void snake(int aty)
{
	system("cls");
	srand((unsigned)time(0));
	system("color 0b");
	clear();
	point head, tail;
	int sew = 1;							//1 ↑ 2 ↓ 3 ←  4 → 
	head.x = 12;
	head.y = 12;
	tail.x = 13;
	tail.y = 12;
	father[13][12] = ret(12, 12);
	map[12][12] = 1;
	print_first();
	setfood();
	gotoxy(12, 12);
	while (1)
	{
		Sleep(1000 / aty);
		while (_kbhit())c = _getch();
	fir:
		switch (c) {
		case 'a':
		{
			if (sew != 2)
				sew = 1;
			break;
		}
		case 'd':
		{
			if (sew != 1)
				sew = 2;

			break;
		}
		case 'w':
		{
			if (sew != 4)
				sew = 3;
			break;
		}
		case 's':
		{
			if (sew != 3)
				sew = 4;
			break;
		}
		case 72:
		{
			c = 'w';
			goto fir;
			break;
		}
		case 75:
		{
			c = 'a';
			goto fir;
			break;
		}
		case 80:
		{
			c = 's';
			goto fir;
			break;
		}
		case 77:
		{
			c = 'd';
			goto fir;
			break;
		}
		}
		px = head.x + fx[sew];
		py = head.y + fy[sew];
		switch (map[px][py])
		{
		case 0:
		{
			map[tail.x][tail.y] = 0;
			print(tail.x, tail.y, 0);
			point _po = rets(father[tail.x][tail.y]);
			tail.x = _po.x;
			tail.y = _po.y;
			map[head.x][head.y] = 2;
			print(head.x, head.y, 2);
			map[px][py] = 1;
			print(px, py, 1);
			father[head.x][head.y] = ret(px, py);
			head.x = px;
			head.y = py;
			break;
		}
		case 1:
		{
			cout << "Fuck!" << endl;
			break;
		}
		case 2:
		{
			map[tail.x][tail.y] = 0;
			map[head.x][head.y] = 2;
			map[px][py] = 1;
			print(tail.x, tail.y, 0);
			print(head.x, head.y, 2);
			print(px, py, 1);
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
			gotoxy(24, 24);
			printf("\nGame over!\n");
			Sleep(1000);
			return;
			break;
		}
		case 3:
		{
			map[head.x][head.y] = 2;
			map[px][py] = 1;
			print(head.x, head.y, 2);
			print(px, py, 1);
			father[head.x][head.y] = ret(px, py);
			head.x = px;
			head.y = py;
			setfood();
			break;
		}
		case 99:
		{
			map[tail.x][tail.y] = 0;
			map[head.x][head.y] = 2;
			map[px][py] = 1;
			print(tail.x, tail.y, 0);
			print(head.x, head.y, 2);
			print(px, py, 1);
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
			gotoxy(24, 24);
			printf("\nGame over!\n");
			Sleep(1000);
			return;
			break;
		}
		}
	}
}

int main()
{
	future<void> result1(async(launch::async, music2));			//启动线程
	snake(8);													//速度设置为8

	flag = 1;
	return 0;
}

 

Add a Comment

Your email address will not be published. Required fields are marked *