Multithreading (Two)
May 12, 2018
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;
}