最近在讀梅拉妮·米歇爾《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