最近在读梅拉妮·米歇尔《AI 3.0》第三部分第九章,谈到学会玩游戏,智能究竟从何而来?
作者: [美] 梅拉妮·米歇尔
出版社: 四川科学技术出版社·湛庐
原作名: Artificial Intelligence: A Guide for Thinking Humans
译者: 王飞跃 / 李玉珂 / 王晓 / 张慧
出版年: 2021-2
装帧: 平装
ISBN: 9787572700378
Google DeepMind团队在强化学习研究工作中将Q学习与DNN相结合,深度Q学习Deep Q-learning和深度Q网络Deep Q-network,监督学习和强化学习之间的核心差异:如何更新权重。强化学习不是将其输出与人类给定的标签进行匹配,而是假设后续迭代给出的值比前面迭代给出的值更好,网络学习的是使其输出在一次迭代到下一次迭代的过程中保持一致。这是深度Q学习如何应用于《打砖块》的工作原理。
系统将其当前状态作为深度Q网络的输入,深度Q网络为每个可能的动作输出一个值,系统选择并执行一个动作,产生一个新的状态。然后,学习开始了:系统将其新状态输入网络,网络为每个动作输出一组新值。新值集与原值集之间的差异被认为是网络的“误差”,这个误差再经过反向传播来改变网络的权重。这些步骤在许多片段中执行,即游戏回合中重复执行。此处的深度Q网络、虚拟操纵杆和游戏本身都是运行在计算机上的软件。
需要一些技巧来对这种算法进行改进和加速。系统从一款游戏中学到的知识,即网络权重,无法迁移到另一款游戏上。每一款游戏,系统都需要经过上千个片段的训练,但是该过程可以通过先进的计算机硬件比较快速地完成。
书中提到二十世纪七八十年代雅达利(英语:Atari,NASDAQ:ATAR),它是美国诺兰·布什内尔在1972年成立的电脑公司。在此回看雅达利的经典游戏主机及其故事。
1974年,19岁的乔布斯从里德学院退学,那是充满自由精神的学校,同时也是美国收费最为高昂的私立大学之一。退学后,乔布斯计划找一份工作来养活自己。雅达利在San Jose Mercury刊登的招聘广告吸引了他。雅达利的广告词是这样写的:Have fun, Make money,又爽又赚钱。
乔布斯到雅达利公司应聘,说自己要得到这份工作,不然不会离开。
下图是乔布斯在雅达利公司填写的个人简历。
时任雅达利首席工程师的阿尔康接到了电话,人事跟阿尔康说道:“公司大厅有个嬉皮士。他说在我们雇佣他之前他不会离开,我们应该报警还是让他进来?”
阿尔康说道:“让他进来吧。”不修边幅的乔布斯让人惊讶,而在与乔布斯的交谈中,阿尔康感受到了这位年轻人对技术的热情,他决定聘用乔布斯。另外一个重要原因是,19岁肄业乔布斯要求的工资并不高。乔布斯成为了雅达利的第40号员工。
才华横溢又喜欢嘲讽同事的乔布斯在雅达利并不讨人喜欢,他不爱洗澡带来的浓烈体味引发了很多投诉。阿尔康对此不以为意,只是让乔布斯晚上来工作,这样就跟大家避开了。
雅达利的工作让乔布斯攒够了去印度修行的钱,他远赴印度修行7个月后,1975年又回到雅达利。
这就是乔布斯如何来到了雅达利。
毫无悬疑地,布什内尔计划用一个新的骗局来压榨阿尔康的生产力。他不知道的是,身为摩羯座的阿尔康是一个自我驱动能力极强的顶尖工程师。
布什内尔告诉阿尔康,他负责的新项目是雅达利跟通用电气公司的合作合同,而不是Bally的产品。通用电气的要求是:游戏街机硬件成本不能高于15美元。阿尔康对此毫不知情,他完全按照布什内尔的意见推动这款产品开发。
某次采访中,记者问到阿尔康当时的场景,阿尔康是这样回答的。
So how did Nolan actually describe the game that became Pong to you? Did he give you a detailed design document?
Oh no, it was just a very general goal: let’s create a ping pong game on a TV screen where you’re looking down on it. One spot that moves, two paddles… just to get that on the screen with the limited technology we had was pretty exciting for me.
翻译起来很简单:阿尔康,你去电视上搞一个乒乓球游戏,一个球动,两个拍子。 搞吧。
单纯的阿尔康,以为这是通用电气的项目,立刻全身心地投入到这个15美元街机方案的开发。为了实现预期的功能,他掏出了自己在Ampex工作时攒下来的硬件。因为开发资金的限制,阿尔康选择了最为物美价廉的TTL逻辑电路,7400系列芯片。对于阿尔康来说,他不仅要完成硬件设计,还要对游戏的体验进行改善。
他做到了。
在设计这款街机游戏时,阿尔康做了一些创新。因为基础游戏太无聊,缺乏变化,阿尔康将球拍分成了八段来改变球的反弹角度。比如正中央以90度返回,而其他的部位则用更小的角度。为了增加乐趣,他还将球进行分段计速,在球被击打十二个回合后,球在比赛中开始加速。
阿尔康让布什内尔试玩,布什内尔提了一些新的意见:比如游戏里有逼真的音效和喧闹的人群声。阿尔康仔细研究了这个产品需求,发现用同步发生器就可以实现击球和得分的音效。这可比米罗华奥德赛强多了,米罗华奥德赛跟早期的默片一样,属于无声游戏。
为了构造原型机,阿尔康在商店里买了一台75美元的日立黑白电视用来做显示设备。这种极限的成本压缩,给布什内尔和达布尼留下了深刻印象,他们认为低价是一种可能的竞争优势。
3个月的努力,阿尔康终于完成了Pong 。布什内尔、达布尼和阿尔康三人反复试玩了这个游戏。布什内尔觉得这款产品挺有吸引力,但有点像换皮的米罗华奥德赛的《网球》。如果拿出去发售,有可能遭遇到专利问题。
阿尔康认为这款产品最大的问题是硬件预算严重超标,远高于之前确定的15美元。而达布尼则认为Pong,可以交给Bally作为合同里那款新的街机方案。二人都同意把这款产品推出去,可布什内尔并不看好Pong。经过一次激烈的争论,布什内尔妥协了:他同意将Pong投放到雅达利的渠道里面试试水,当然,那是拉尔斯丁转让给他们的销售渠道。
在米罗华奥德赛和 Computer Space的普通表现后,电子游戏艺术史上第一个爆款游街机,就要上场了。
取得一致后,达布尼迅速完成了外壳、控制面板和投币装置的制作。他将其中的一台《Pong》送到了位于加利福尼亚州桑尼维尔的安迪·卡普 (Andy· Capp) 酒馆。这台看起来粗制滥造的街机就放在酒吧的酒桶上,没有任何说明。而阿尔康和达布尼则一人拿了一瓶啤酒,等待接下来发生的事情。
喝啤酒的时候,开始有人投币来尝试玩《Pong》。这台街机游戏的优势在于,不需要说明书,就可以让玩家知道自己要做什么。当晚,没有发生任何奇迹。
奇迹发生在一周后。
一周后,酒吧老板比尔打来电话,说机器坏了。
阿尔康一点都不惊讶,因为他知道这台原型机只是为了展示,而不是商用。只要轻轻一撞,它可能就要罢工。让阿尔康惊讶的是,它竟然可以撑到这么久才坏。
下班后,阿尔康带着工具去到了安迪·卡普酒馆,这时已经有几个人等在机器前面,埋怨他为什么姗姗来迟。作为Pong的发明者,阿尔康还挺惊讶这台机器竟然拥有了不少粉丝。等到他打开机器一看,发现投币箱竟然满了,里面有400多个25美分的硬币。
一周100美元,这个成绩相当不错了。
当阿尔康把这个消息告诉布什内尔时,布什内尔的回答是:这很有趣。
照片摄于1973年。
从左到右:左一:泰德·达布尼、左二:诺兰·布什内尔、左三:弗雷德·马林希克、左四:艾尔·阿尔康。
布什内尔带着另外一台Pong 去了芝加哥,想用这个替代之前Bally方案里所说的冰球游戏。
Bally觉得这个游戏有那么点意思,但是比起布什内尔之前提出要做的冰球街机,差得不是一点半点。Bally不想接受Pong,但是仍然推荐布什内尔将游戏卖给自己的子公司:Midway,可Midway同样看不上。
虽说好马不吃回头草,可脸皮极厚的布什内尔找到了曾经的东家,Nutting公司。没想到老板纳廷不仅表达了对Pong的蔑视,而且落井下石地说,自己找到新人来设计双人Computer Space街机游戏,原来的合同作废了。
没有人愿意给雅达利生产Pong,布什内尔抱着生产样机的目的,继续生产这台新型街机。1972年10月到11月之间,雅达利造出了12台Pong。这12台机器,10台送到了酒吧,1台留在公司,1台送给了Bally。
几周内,这10台机器就带来了非常可观的收入。布什内尔拿着Pong的市场反馈数据,想再一次说服Bally。怕Bally认为他们在数据中灌水,布什内尔还把数据压低了2/3 。即便如此,Bally还是不愿意接受雅达利Pong的设计方案。按照合约,如果Bally不明确拒绝Pong街机方案,雅达利不能生产,也不能授权其他厂商生产。
万般无奈,布什内尔提议:雅达利应该尝试自己生产Pong街机。
达布尼和阿尔康不同意他的提议,因为这个操作太过于冒险。Bally家大业大,雅达利如果故意违约,赔偿的金额可不是小数目。可二人明显架不住布什内尔的说服力,同意了由雅达利自己生产街机的方案。
三人与达布尼的兄弟一起组装出50台Pong街机,因为自己的仓库不够用,还在墙壁上打了一个洞,用上了隔壁闲置的库房。
此时Bally回复说,他们对Pong不感兴趣,按照合同条款,雅达利仍然要给Bally设计一款弹珠机。这就是明确拒绝了Pong方案了,布什内尔他们如释重负,开启了疯狂接单模式。
为了满足市场需求,布什内尔需要更多的资金来生产Pong街机。钱从哪里来呢?布什内尔跑了许多银行,银行家都认为Pong街机是弹珠机的变种。而在1970年的美国,弹珠机总会被跟黑手党联系到一起,所以布什内尔没能从银行贷到款。
直到富国银行给布什内尔贷了5万美元,才解决雅达利的资金问题。
Tips:
富国银行是巴菲特投资超32年的银行,也是巴菲特最成功的投资案例之一。
布什内尔买下了公司附近的一栋楼,开始招聘新员工生产Pong街机和送货,1972年12月,雅达利开始正式配送新的街机。
1973年2月后,雅达利已经可以向国外发货,Pong街机正式走向了全球。
对于一家年轻的公司,火爆的生意带来了大量新的考验。
Pong街机影响深远,是雅达利的开山之作,下一步的雅达利将走向何方呢?
1977年发行的雅达利Atari 2600 主机,商标Atari。
雅达利经典的游戏如银河小行星Aster-oids,太空入侵者Space-Invaders,乒乓Pong,吃豆人Pac-Man,打砖块Breakout等等。
Atari 2600 可分离式手柄、可更换卡带的设计思路延续至今,现在来看依然非常经典。凭借出色游戏软件和游戏设备,雅达利带领游戏行业从「蛮荒时代」逐渐走向了成熟。
由操纵杆控制的游戏对小孩子而言特别容易学,但是要让成年人保持兴趣却很难。
通过下面这个简短的故事,一起来感受下历史的脉搏:在 1972 年的美国,那时候的街机游戏机没有电脑主机,只能在芯片上集成晶体管电路,让晶体管控制电路开关,但是由于晶体管价格昂贵,每增加一个都是真金白银!所以雅达利一直希望能够在游戏设计中,减少芯片中晶体管的数量,那时候雅达利的员工制作一款游戏大约需要用到 150 个晶体管左右。这也让制作一台游戏机的成本一直很高。
史蒂夫·乔布斯(Steve Jobs)在好友斯蒂夫·盖瑞·沃兹尼亚克(Stephen Gary Wozniak)(当时他还在惠普工作)的帮助下设计了游戏《Breakout》,也就是「打砖块」游戏的鼻祖。实际上,《Breakout》可以理解为《Pong》的单机版本,后者是雅达利的首款电子游戏,也被誉为史上第一款街机电子游戏,需要两名玩家进行对战。
乔布斯告诉沃兹:必须要在 4 天之内完成设计,并且用尽可能少的芯片。完成工作之后的奖金,他们对半分。在接下来的四天里,两人几乎不眠不休,乔布斯负责创作原型和测试,沃兹负责技术方面的工作。没想到的是,这两位大佬还真在 4 天内做出做出了这款可以永远载入游戏历史的《 打砖块 》,并且整款游戏仅仅用了 44 个晶体管!
雅达利2600 Breakout于1976年5月13日发布。
游戏包括在屏幕的前三分之一铺上一层砖,玩家的目标是通过反复将球从球拍上弹到砖中来摧毁它们。1978年发布的雅达利VCS端口使用彩色图形,而不是彩色覆盖的单色屏幕。
粉碎!POW!屏幕顶部会出现一堵砖墙,你的任务是从游戏场上砸碎两堵墙——一块砖一块砖。使用控制器在屏幕底部移动拨杆。用球拍把球打到墙上。每次球碰到砖块,砖块就会消失,你就得分了。一个球员或球队每场比赛能得到五个球。当你用球拍打丢一个球时,球就会从屏幕上消失。按下红色控制器按钮,再发球一个球,直到五个球都打完为止。
Original Release: 1978
Action / Skill
One / Two Player
Original Code: CX2622
此外,Breakout是后续电脑应用程序某些方面的基础和灵感来源。
C语言复刻打砖块游戏:
#include <graphics.h>
#include <time.h>
//画砖块
int map[5][8];//描述整个地图
HWND hwnd = NULL;
//用1-3 给数组赋值
void initMap()
{for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++) {map[i][j] = rand() % 3 + 1;}}
}
void drawMap()
{setlinestyle(PS_SOLID, 2);setlinecolor(WHITE);for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++){int x = 100*j ; //j=x/100int y = 25*i ; //i=y/iswitch (map[i][j]) //map[i][j]!=0{case 0: //做消除用的break;case 1:setfillcolor(YELLOW);fillrectangle(x, y, x + 100, y + 25);break;case 2:setfillcolor(LIGHTBLUE);fillrectangle(x, y, x + 100, y + 25);break;case 3:setfillcolor(LIGHTGREEN);fillrectangle(x, y, x + 100, y + 25);break;}}}
}
//木板的过程
struct Board
{int x;int y;int speed;COLORREF color;int width;int height;
};
//struct Board board = { 300, 800 - 25,1, WHITE, 200, 25 };
struct Board* createBoard(int x, int y, int speed, COLORREF color, int width, int height)
{struct Board* pBoard = (struct Board*)malloc(sizeof(struct Board));//结构体指针->成员 ->指针指向运算符//(*指针).成员;pBoard->x = x;pBoard->y = y;pBoard->speed = speed;pBoard->color = color;//结构体变量.成员(*pBoard).width = width;(*pBoard).height = height;return pBoard;
}
void drawBoard(struct Board* pBoard)
{setfillcolor(pBoard->color);fillrectangle(pBoard->x, pBoard->y,pBoard->x + pBoard->width, pBoard->y + pBoard->height);
}
//木板的按键操作
void keyDown(struct Board* pBoard)
{//C语言: scanf函数 getch() getchar() gets()//异步的按键操作if (GetAsyncKeyState('A') || GetAsyncKeyState(VK_LEFT)&&pBoard->x>=0) {pBoard->x -= pBoard->speed;}if (GetAsyncKeyState('D') || GetAsyncKeyState(VK_RIGHT)&&pBoard->x<=800-200) {pBoard->x += pBoard->speed;}
}
//球:
struct Ball
{int x;int y;int r; //半径int dx;int dy;COLORREF color;
};
struct Ball* createBall(int x, int y, int r, int dx, int dy, COLORREF color)
{struct Ball* pBall = (struct Ball*)malloc(sizeof(struct Ball));pBall->x = x;pBall->y = y;pBall->r = r;pBall->dx = dx;pBall->dy = dy;pBall->color = color;return pBall;
}
void drawBall(struct Ball* pBall)
{setfillcolor(pBall->color);solidcircle(pBall->x, pBall->y, pBall->r);
}
//1.反射
//2.撞击木板
int hitBoard(struct Ball* pBall, struct Board* pBoard)
{if (pBall->y + pBall->r == pBoard->y) //y满足{if (pBall->x >= pBoard->x && pBall->x <= pBoard->x + pBoard->width) {return 1;}}return 0;
}
int die(struct Ball* pBall)
{if (pBall->y > 800 - 25){return 1;}return 0;
}
//3.撞击砖块
int hitBricks(struct Ball* pBall)
{//1.算出球的行的列是属于地图int ballJ = pBall->x / 100;int ballI = (pBall->y - pBall->r) / 25;//2.当前下标下,数组中不等于表示有砖块需要反射if (ballJ < 8 && ballI < 5 && map[ballI][ballJ] != 0) {map[ballI][ballJ] = 0;return 1;}return 0;
}
void moveBall(struct Ball* pBall,struct Board* pBoard)
{if (pBall->x - pBall->r <= 0 || pBall->x + pBall->r >= 800) {pBall->dx = -pBall->dx;}if (pBall->y - pBall->r <= 0 || hitBoard(pBall,pBoard)|| hitBricks(pBall)){pBall->dy = -pBall->dy;}pBall->x += pBall->dx;pBall->y += pBall->dy;
}
//4.收尾工作 :游戏结束
//5.定时器
int Timer(time_t num, int id)
{static time_t start[10];time_t end = clock();if (end - start[id]>num) {start[id] = end;return 1;}return 0;
}
int gameOver()
{for (int i = 0; i < 5; i++) {for (int j = 0; j < 8; j++) {if (map[i][j] != 0) {return 0;}}}return 1;
}
int main()
{srand((unsigned int)time(0)); //设置随机数的范围跟随时间改变而改变hwnd=initgraph(800, 800);struct Board* pBoard = createBoard(300, 800 - 25,5, WHITE, 200, 25);struct Ball* pBall = createBall(400, 600, 15, 5, -5, RED);initMap();BeginBatchDraw();while (1) {cleardevice();drawMap();drawBoard(pBoard);drawBall(pBall);if(Timer(10,0))moveBall(pBall,pBoard);keyDown(pBoard);if (die(pBall)) {MessageBox(hwnd, "you die", "gameOver", MB_OK);exit(0);}if (gameOver()) {MessageBox(hwnd, "win game", "gameOver", MB_OK);exit(0);}FlushBatchDraw();}EndBatchDraw();closegraph();return 0;
}
离开雅达利之后,乔布斯便和沃兹尼亚克创办了苹果电脑公司(后来改名为苹果公司)。
雅达利游戏的简洁性和用户友好性影响着日后苹果的产品设计,而布什内尔本人的性格也深深地影响了乔布斯。
布什内尔强势的态度、享乐主义的精神潜移默化塑造了乔布斯的性格,而乔布斯的「现实扭曲力场」也被认为是受到了布什内尔的影响。「我告诉他,装得好像你掌控了一切,别人就会以为你真的掌控了一切。」
虽然后来的雅达利命运多舛,但那些离开雅达利公司的人将其「在享乐中赚钱」的企业文化继续发扬光大。
「雅达利就是硅谷文化的源头。」
2022年初雅达利50周年,还在这部打砖块的新作品中还加入了双人模式、无休止的街机模式、五十个挑战级别,轨道炮、导弹和炸药等等,全新的元素。游戏整个的赛博朋克画风也非常抓人眼球。
参见:
雅达利庆祝成立 50 周年,推出历史游戏 100+款合集_腾讯新闻
AI 3.0 (豆瓣)
25 Best Atari 2600 Games From The Golden Age Of Gaming
Google DeepMind
Motherboard Graphics by Ron Reuter
Breakout – Atari®
Breakout (Atari 2600) online game | AtariOnline.org
Atari 2600 Breakout Benchmark (Atari Games) | Papers With Code
STEVE JOBS' 'DIGITAL HUB STRATEGY
Atari Games | Papers With Code
https://arxiv.org/pdf/1312.5602v1.pdf