c++day8

适配器

取反适配器
一元取反适配器

class g5:public unary_function<int,bool>
{
public:
	bool operator()(int v) const {
		return v > 5;
	}
};

int main()
{
	vector<int> v(10);
	for (int i = 0; i < 10; i++)
		v[i] = i;


	vector<int>::iterator it = find_if(v.begin(), v.end(),not1(g5()) );

	cout << *it << endl;
	return 0;
}

函数指针适配器

void func(int v,int start)
{
	cout << v << endl;
}
void test03()
{
	vector<int> v;
	int n;
	cin >> n;
	for_each(v.begin(),v.end(),bind2nd(ptr_fun(func),n));
}

成员函数适配器

class person{
public:
	void func();
};
vector<person> v;//假如为vector<person*> v;  就用mem_fun
for_each(v.begin(),v.end(),mem_fun_ref(&person::func);//成员函数适配器
class person:继承两个类
find_if(v.begin(),v.end(),not1(bind2nd(greater<int>,num)))

常用算法

常用遍历算法

struct person{
	void operator()(int v)
	{
		cout << v << endl;
	}
};//这样也是仿函数,struct 作用域默认为public
person p = for_each(v.begin(),v.end(),person());//返回值为一个对象,可以保存内部记录
//transform算法,将指定容器区间元素搬运到另一元素中,要提前给目标容器分配好内存
class tra{
public:
	int operator()(int val){
		return val;//return v + n;
	}
};

vector<int> v1;
vector<int> v2(10);//也可以用reserve函数

transform(v1.begin(),v1.end(),v2.begin(),tra());//为什么用仿函数呢,因为到时候可以用适配器,增加策略

//第二种用法 将两个容器数据进行运算后搬运到第三个容器
class tra2{
public:
	int operator()(int v1,int v2){
		return v1 + v2;
	}
}
vector<int> v3(10);
trsform(v1.begin(),v1.end(),v2.begin(),v3.begin(),tra2());

常用查找算法

//find 和 find_if 差别就是find 已经给你定义好了底层 而find_if需要自己写仿函数实现
vector<int>::iterator it = find(v.begin(),v.end(),num);//找为num的这个数
//若为自定义类型,要重载自定义类型中的 == 符号
//不能传指针,传指针只能用find_if,要用适配器
//adjacent_find 查找相邻重复元素 不用指定元素,只能返回第一个找到的 例如 1 3 4 5 5 6 6,就返回第一个5的迭代器
adjacent_find(v.begin(),v.end());
//binary_search 二分查找法,在无序序列不可用
if(binary_search(v.begin(),v.end(),elem))	//返回值为bool类型
//count统计元素出现个数
int n = count(v.begin(),v.end(),elem);
//count_if
int n = count_if(v.begin(),v.end(),bind2nd(greater<int>,elem));

常用排序算法

//merge算法 容器元素合并,并存储到另一容器中 这两个容器,必须也是有序的
vector<int> v1;
vector<int> v2;

vector<int> target;
target.resize(v1.size()+v2.size());

merge(v1.begin(),v1.end(),v2.begin(),v2.end(),ttarget.begin());
//sort
//random_shuffle算法 洗牌算法
//随机数种子
srand((unsigned int)time(NULL));
random_shuffle(v.begin(),v.end());//随机算法,打乱顺序
//reverse算法反转指定范围元素
reverse(v.begin(),v.end());

常用拷贝和替换算法

//copy算法,将一个容易指定范围的元素拷贝到另一容器中 当然要提前开辟空间
copy(v1.begin(),v1.end(),v2.begin());

//#include <iterator>
copy(v1.begin(),v1.end(),ostream_iterator<int>(cout," "));//copy到流迭代器中,然后打印
//replace 替换
replace(v.begin(),v.end(),oldelem,newelem);//把旧的值替换为新的值
//replace_if
replace_if(v.begin(),v.end(),bind2nd(greater<int>(),oldelem),newelem);//把所有满足某个条件的值替换为newelem
//swap交换两个容器的元素
swap(v1,v2);

常用算数生成算法

//accmulate 计算容器元素累计合
#include <numeric>
int value = 0;//作为起始累加值
int sum = accmulate(v.begin(),v.end(),value);//总和为sum
//fill 填充容器
fill(v.begin(),v.end(),n);//n为要填充进去的值

常用集合算法

//set_intersection 求两个集合的交集,两个集合必须为有序序列
vector<int>::iterator it = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
//v1,v2为两个集合,v3为目标集合,返回值为目标容器最后一个元素的迭代器地址
//set_union 求两个集合的并集 
//set_difference 求两个集合差集

贪吃蛇案例完整代码实现

#pragma once
#include <iostream>
using namespace std;
#include "wall.h"
class Food {
public:
	Food(Wall& tempwall);
	void setFood();
	int foodX;
	int foodY;
	Wall &wall;
};
#include "food.h"
#include <windows.h>
void gotoxy2(HANDLE hOut2, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
	COORD pos;
	pos.X = x;             //横坐标
	pos.Y = y;            //纵坐标
	SetConsoleCursorPosition(hOut2, pos);
}
HANDLE hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);

Food::Food(Wall & tempwall):wall(tempwall)
{

}

void Food::setFood()
{
	while (true) {
		foodX = rand() % (Wall::ROW - 2) + 1;
		foodY = rand() % (Wall::COL - 2) + 1;
		if (wall.getWall(foodX, foodY) == ' '){
			wall.setWall(foodX, foodY, 'o');
			gotoxy2(hOut2, foodY * 2, foodX);
			cout << 'o';
			break;
		}
	}
}
#pragma once
#include <iostream>
using namespace std;
#include "wall.h"
#include "food.h"
class Snake {
public:
	struct Point
	{
		int x;
		int y;
		Point *next;
	};
	enum {
		UP = 'w',
		DOWN = 's',
		LEFT = 'a',
		RIGHT = 'd'
	};
	Snake(Wall &tempwall,Food &tempfood);
	void initSnake();
	void delSnake();
	void addPoint(int x,int y);
	void delPoint();
	bool move(char key);
	Point *pHead;
	Wall &wall;
	Food &food;
	bool isRool;
};
#include "snake.h"
#include <windows.h>
void gotoxy1(HANDLE hOut1, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
	COORD pos;
	pos.X = x;             //横坐标
	pos.Y = y;            //纵坐标
	SetConsoleCursorPosition(hOut1, pos);
}
HANDLE hOut1 = GetStdHandle(STD_OUTPUT_HANDLE);

Snake::Snake(Wall & tempwall, Food &tempfood):wall(tempwall),food(tempfood)
{
	pHead = NULL;
	isRool = false;
}



void Snake::initSnake()
{
	delSnake();
	addPoint(5, 3);
	addPoint(5, 4);
	addPoint(5, 5);
}

void Snake::delSnake()
{
	Point *pCur = pHead;
	while (pHead != NULL) {
		pCur = pHead->next;
		delete pHead;
		pHead = pCur;
	}
}

void Snake::addPoint(int x, int y)
{
	Point *newp = new Point;
	newp->x = x;
	newp->y = y;
	newp->next = NULL;
	if (pHead != NULL) {
		wall.setWall(pHead->x, pHead->y, '*');
		gotoxy1(hOut1,pHead->y * 2, pHead->x);
		cout << '*';
	}
	newp->next = pHead;
	pHead = newp;
	wall.setWall(pHead->x, pHead->y, '@');
	gotoxy1(hOut1, pHead->y * 2, pHead->x);
	cout << '@';
}

void Snake::delPoint()
{
	if (pHead == NULL || pHead->next == NULL)
		return;
	Point *phead = pHead;
	Point *p = phead->next;
	while (p->next != NULL)
	{
		phead = phead->next;
		p = p->next;
	}
	wall.setWall(p->x, p->y, ' ');
	gotoxy1(hOut1, p->y * 2, p->x);
	cout << ' ';
	delete p;
	p = NULL;
	phead->next = NULL;
}

bool Snake::move(char key)
{
	int x = pHead->x;
	int y = pHead->y;
	switch (key) {
	case UP:
		x--;
		break;
	case DOWN:
		x++;
		break;
	case LEFT:
		y--;
		break;
	case RIGHT:
		y++;
		break;
	default:
		break;
	}
	
	Point *phead = pHead;
	Point *p = phead->next;
	while (p->next != NULL)
	{
		phead = phead->next;
		p = p->next;
	}//判断,如果是尾巴,就不删除
	if (x == p->x && y == p->y) {
		isRool = true;
	}
	else {
		if (wall.getWall(x, y) == '#' || wall.getWall(x, y) == '*') {
			addPoint(x,y);
			delPoint();
			//system("cls");
			//wall.drawWall();
			gotoxy1(hOut1, 0, 26);
			cout << "GAME OVER!!" << endl;
			return false;
		}	
	}
	if (wall.getWall(x, y) == 'o') {
		addPoint(x, y);
		food.setFood();
	}
	else {
		addPoint(x, y);
		delPoint();
		if (isRool == true) {
			wall.setWall(x, y, '@');
			gotoxy1(hOut1, y * 2, x);
			cout << '@';
		}
	}
	return true;
}


#ifndef _WALL_HEAD
#define _WALL_HEAD
#include <iostream>

using namespace std;

class Wall {
public:
	enum {
		ROW = 26,
		COL = 26
	};//初始化墙壁
	void initWall();
	void drawWall();
	void setWall(int x,int y,char c);//根据索引设置二维数组里面的内容
	char getWall(int x,int y);//获取当前位置的符号
private:
	char gameArray[ROW][COL];
};

#endif
#include "wall.h"


void Wall::initWall()
{
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++) {
			if (i == 0 || j == 0 || i == ROW - 1 || j == COL - 1)
				gameArray[i][j] = '#';
			else
				gameArray[i][j] = ' ';
		}
	}
}

void Wall::drawWall()
{
	for (int i = 0; i < ROW; i++) {
		for (int j = 0; j < COL; j++)
			cout << gameArray[i][j] << " ";
		if (i == 5) cout << "小蛇名字:杨振";
		if (i == 6) cout << "版本号:250 gamename:贪吃蛇";
		cout << endl;
	}
}

void Wall::setWall(int x, int y, char c)
{
	gameArray[x][y] = c;
}

char Wall::getWall(int x, int y)
{
	return gameArray[x][y];
}

#include <iostream>
#include <ctime>
#include <conio.h>
#include <windows.h>
using namespace std;
#include "wall.h"
#include "snake.h"
#include "food.h"

void gotoxy(HANDLE hOut, int x, int y)//其中x,y是与正常理解相反的,注意区分
{
	COORD pos;
	pos.X = x;             //横坐标
	pos.Y = y;            //纵坐标
	SetConsoleCursorPosition(hOut, pos);
}
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

int main()
{
	srand((unsigned int)time(NULL));

	bool isDead = false;

	char preKey = NULL;
	Wall wall;
	wall.initWall();

	wall.drawWall();//这一步特别重要

	Food food(wall);
	food.setFood();
	Snake snake(wall,food);
	snake.initSnake();
	
	while (!isDead) {
		char key = _getch();
		if (key == snake.LEFT && preKey == NULL) {
			continue;
		}
		do {
			
			if (key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT || key == snake.UP)
			{
				if ((key == snake.LEFT && preKey == snake.RIGHT) ||
					(key == snake.RIGHT && preKey == snake.LEFT) ||
					(key == snake.DOWN && preKey == snake.UP) ||
					(key == snake.UP && preKey == snake.DOWN)) {
					key = preKey;
				}
				else {
					preKey = key;
				}
				if (snake.move(key) == true) {
					//system("cls");
					//wall.drawWall();
					Sleep(100);
				}
				else {
					isDead = true;
					break;
				}
			}
			else {
				key = preKey;//输入其他按键,强制为上一次正确输入的案件
			}
		} while (!_kbhit());//当没有键盘输入,返回0
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值