提交 54d012cb 编写于 作者: W wizardforcel

2021-01-06 17:20:22

上级 d8811fc0
......@@ -718,7 +718,7 @@ def download(fname):
return send_file("Output/"+fname, mimetype="audio/midi", as_attachment=True)
```
请注意,前面的函数在`/download/filename`路由上起作用,在该路由上,客户端根据上一代 API 调用的输出提供文件名。 下载的文件的 MIME 类型为 audio / midi,它告诉客户端它是 MIDI 文件。
请注意,前面的函数在`/download/filename`路由上起作用,在该路由上,客户端根据上一代 API 调用的输出提供文件名。 下载的文件的 MIME 类型为`audio/midi`,它告诉客户端它是 MIDI 文件。
9. 最后,我们可以添加将执行此服务器的代码:
......@@ -875,7 +875,7 @@ AudioPlayer audioPlayer = AudioPlayer();
```py
play() async {
var url = http://34.70.80.18:8000/download/output_1573917221.mid;
var url = 'http://34.70.80.18:8000/download/output_1573917221.mid';
int result = await audioPlayer.play(url);
if (result == 1) {
print('Success');
......
......@@ -31,7 +31,7 @@
* **状态**`S`):所有方案的集合,以及其中可用的配置。
* **奖励**`R`):对于代理执行的任何操作返回的值,然后代理尝试将其最大化。
* **策略**`π`):代理用来确定接下来必须执行哪些操作的策略。
* **值**`V`):R 是短期每动作奖励,而值是在一组动作结束时预期的总奖励。 Vπ(s)通过遵循状态 S 下的策略π来定义预期的总回报。
* **值**`V`):`R`是短期每动作奖励,而值是在一组动作结束时预期的总奖励。`V[π](s)`通过遵循状态`S`下的策略`π`来定义预期的总回报。
下图显示了该算法的流程:
......@@ -49,7 +49,7 @@
让我们考虑一个简单的游戏,例如井字棋。 另外,如果您觉得古怪,只需使用 Google 搜索*井字棋*,您就会在搜索结果中看到一个游戏!
考虑您正在用计算机玩井字棋。 这里的计算机是代理。 在这种情况下,环境是什么? 您猜对了–井字棋板以及在环境中管理游戏的一组规则。 井字棋盘上已经放置的标记可以确定环境所在的状态。座席可以在棋盘上放置的 X 或 O 是他们可以执行的动作,即输掉,赢得比赛或平局。 或朝着损失,胜利或平局前进是他们执行任何行动后回馈给代理商的奖励。 代理商赢得比赛所遵循的策略是遵循的策略。
考虑您正在用计算机玩井字棋。 这里的计算机是代理。 在这种情况下,环境是什么? 您猜对了–井字棋板以及在环境中管理游戏的一组规则。 井字棋盘上已经放置的标记可以确定环境所在的状态。座席可以在棋盘上放置的`X``O`是他们可以执行的动作,即输掉,赢得比赛或平局。 或朝着损失,胜利或平局前进是他们执行任何行动后回馈给代理商的奖励。 代理商赢得比赛所遵循的策略是遵循的策略。
因此,从该示例可以得出结论,强化学习代理非常适合构建学习玩任何游戏的 AI。 这导致许多开发人员想出了象围棋,跳棋,反恐精英等国际象棋以外的几种流行游戏的游戏 AI。 甚至 Chrome Dino 之类的游戏也发现开发人员试图使用 AI 进行游戏。
......@@ -61,7 +61,7 @@
# AlphaGo
2015 年,AlphaGo 成为第一个在 19x19 董事会上击败职业围棋选手 Lee Sedol 的计算机软件。 突破被记录下来并作为纪录片发行。 击败李·塞多尔的影响如此之大,以至于韩国 Baduk 协会授予了荣誉 9 丹证书,这实际上意味着 Go 球员的游戏技能与神性息息相关。 这是 Go 历史上第一次提供 9 荣誉荣誉证书,因此提供给 AlphaGo 的证书编号为 001。ELO 等级为 3,739。
2015 年,AlphaGo 成为第一个在`19x19`棋盘上击败职业围棋选手 Lee Sedol 的计算机软件。 突破被记录下来并作为纪录片发行。 击败李·塞多尔的影响如此之大,以至于韩国 Baduk 协会授予了荣誉 9 丹证书,这实际上意味着围棋选手的游戏技能与神性息息相关。 这是围棋历史上第一次提供 9 荣誉荣誉证书,因此提供给 AlphaGo 的证书编号为 001。ELO 等级为 3,739。
AlphaGo Master 的继任者 AlphaGo Master 在三场比赛中击败了当时统治世界的游戏冠军 Ke Jie。 为了表彰这一壮举,它获得了中国围棋协会颁发的 9 丹证书。 该软件当时的 ELO 等级为 4,858。
......@@ -132,7 +132,7 @@ AlphaGo Zero 和 Alpha Zero 变体之间的主要区别如下:
# 适用于 Connect 4 的 Alpha 类零 AI
在开始研究可玩 Connect4 的 AI 之前,让我们简要了解一下游戏及其动态。 Connect 4,有时也称为连续四人,连续四人,四人以上,等等,是全世界儿童中最受欢迎的棋盘游戏之一。 我们也可以将它理解为井字棋的更高级版本,在其中您必须水平,垂直或对角放置三个相同类型的标记。 棋盘通常是一个 6x7 的网格,两个玩家各自玩一个标记。
在开始研究可玩 Connect4 的 AI 之前,让我们简要了解一下游戏及其动态。 Connect 4,有时也称为连续四人,连续四人,四人以上,等等,是全世界儿童中最受欢迎的棋盘游戏之一。 我们也可以将它理解为井字棋的更高级版本,在其中您必须水平,垂直或对角放置三个相同类型的标记。 棋盘通常是一个`6x7`的网格,两个玩家各自玩一个标记。
Connect 4 的规则可能会有所不同,因此让我们为 AI 将学习的规则版本制定一些具体规则:
......@@ -144,7 +144,7 @@ Connect 4 的规则可能会有所不同,因此让我们为 AI 将学习的规
现在,让我们分解将 Connect 4 播放式自学 AI 分解为子问题的问题:
1. 首先,我们需要创建董事会的虚拟代表。
1. 首先,我们需要创建棋盘的虚拟代表。
2. 接下来,我们必须创建允许根据游戏规则移动的函数。
3. 然后,为了保存游戏状态,我们需要一个状态管理系统。
4. 接下来,我们将简化游戏玩法,其中将提示用户进行移动并宣布游戏终止。
......@@ -177,7 +177,7 @@ Connect 4 的规则可能会有所不同,因此让我们为 AI 将学习的规
接下来,我们将继续探索这些文件中每个文件的一些重要部分,同时遵循我们先前为构建 AI 制定的步骤。
# 创建董事会的虚拟代表
# 创建棋盘的虚拟代表
您将如何代表 Connect 4 开发板? 代表 Connect 4 开发板的两种常用方法以及游戏状态。 让我们来看看:
......@@ -243,7 +243,7 @@ LIST4 += [[(y, x), (y + 1, x), (y + 2, x), (y + 3, x)] for y in range(BOARD_SIZE
* `get_action(board)`:此函数返回播放器已修改的数组中的位置。
* `action_to_string(action)`:此功能将玩家执行的动作的内部数字表示形式转换为可以以易于理解的形式显示给用户的字符串。 例如`place_at(board, pos,`
* `player)`:执行为任何给定玩家在板上放置一块棋子的动作。 它还会更新板。
* `def get_winner(board)`:此功能确定棋盘当前状态下的游戏是否有赢家。 如果是,则返回获胜玩家的标识符,该标识符将为 1 或-1。
* `def get_winner(board)`:此功能确定棋盘当前状态下的游戏是否有赢家。 如果是,则返回获胜玩家的标识符,该标识符将为 1 或 -1。
* `def to_string(board)`:此函数将板的 NumPy 数组表示形式转换为字符串,该字符串为人类可读的格式。
接下来,我们将研究如何对 AI 进行编程,使其根据游戏规则进行并仅接受有效的动作。
......@@ -367,7 +367,7 @@ def getRepresentativeString(self):
状态类中的许多其他重要方法如下:
* `getCurrentPlayer(self)`:此方法返回游戏的当前玩家; 也就是说,应该采取行动的球员
* `getCurrentPlayer(self)`:此方法返回游戏的当前玩家; 也就是说,应该采取行动的玩家
* `getWinner(self)`:如果游戏结束,则此方法返回游戏获胜者的标识符。
* `getAction(self)`:此方法检查游戏是否结束。 如果没有,它将在任何给定状态下返回一组下一个可能的动作。
* `getNextState(self, action)`:此方法返回游戏的下一个状态; 也就是说,在将当前正在移动的棋子放在棋盘上并评估游戏是否结束之后,它将执行从一种状态到另一种状态的切换。
......@@ -394,7 +394,7 @@ def fight(self, state, p1, p2, count):
print('stats', stats[::-1])
```
前面的`fight()`功能管理玩家的胜利/损失或平局的状态。 它确保在每个回合中进行两场比赛,其中每位球员只能先玩一次。
前面的`fight()`功能管理玩家的胜利/损失或平局的状态。 它确保在每个回合中进行两场比赛,其中每位玩家只能先玩一次。
此类中定义的另一个`_fight()`函数如下:
......@@ -681,11 +681,11 @@ bestmove b8c6
第一步将是请求增加 GPU 实例的配额。 默认情况下,您的 GCP 帐户上可拥有的 GPU 实例数为 0。此限制由您的帐户的配额配置设置,您需要请求增加。 这样做,请按照下列步骤操作:
1. 通过[这里](https://console.cloud.google.com/)打开 Goog​​le Cloud Platform 控制台。
2. 在左侧菜单上,单击 IAM&Admin | 配额,如以下屏幕截图所示:
2. 在左侧菜单上,单击“IAM&Admin | 配额”,如以下屏幕截图所示:
![](img/25490c0c-99fb-42a9-a522-42e94bc72bc7.png)
3. 单击 Metrics 过滤器,然后键入 GPU 以找到读取 GPU(所有区域)的条目,如以下屏幕截图所示:
3. 单击`Metrics`过滤器,然后键入 GPU 以找到读取 GPU(所有区域)的条目,如以下屏幕截图所示:
![](img/b6b7fbc0-b10d-43ea-8120-a55d267ce48f.png)
......@@ -700,13 +700,13 @@ bestmove b8c6
下一步是创建 GPU 实例。 创建 GPU 实例的过程与创建非 GPU 实例的过程非常相似,但是需要额外的步骤。 让我们快速完成所有这些步骤:
1. 在您的 Google Cloud Platform 仪表板上,单击 Compute Engine | 左侧导航菜单中的 VM 实例
1. 在您的 Google Cloud Platform 仪表板上,单击左侧导航菜单中的“Compute Engine | VM 实例”
2. 单击创建实例。
3. 单击“计算机类型选择”部分正下方的 CPU 平台和 GPU,如以下屏幕截图所示:
![](img/c8e5a150-c87a-477c-b2a5-25de4d03a540.png)
4. 单击添加 GPU(大加号(+)按钮)。 选择要附加到此 VM 的 GPU 类型和 GPU 数量。
4. 单击添加 GPU(大加号(`+`)按钮)。 选择要附加到此 VM 的 GPU 类型和 GPU 数量。
5. 将启动盘操作系统更改为 Ubuntu 版本 10.10。
6. 在“防火墙”部分中,检查 HTTP 和 HTTPS 通信权限,如以下屏幕截图所示:
......@@ -879,7 +879,7 @@ Request body:
我们告诉服务器这是怀特的举动,而怀特玩家的举动是`f3g5`,这意味着将怀特骑士移动到板上的 G5 位置。 我们传递给 API 的棋盘 FEN 字符串中的`'w'`表示白人玩家将进行下一回合。
引擎通过将 H7 处的棋子移动到 H6 进行响应,威胁到 Knight 的前进,如以下屏幕快照所示:
引擎通过将 H7 处的棋子移动到 H6 进行响应,威胁到的前进,如以下屏幕快照所示:
![](img/bafe5b9f-bf74-4f11-bc7c-f599f0124bf6.png)
......@@ -899,7 +899,7 @@ Request body:
让我们开始编写应用程序代码。
# 将依赖项添加到 pubspec.yaml
# 将依赖项添加到`pubspec.yaml`
首先,将`chess_vectors_flutter`包添加到`pubspec.yaml`文件中,以便在将要构建的棋盘上显示实际的棋子。 将以下行添加到`pubspec.yaml`的依赖项部分:
......@@ -930,13 +930,13 @@ var squareList = [
];
```
2. 为了将正确的棋子存储在正确的正方形中并根据玩家的移动来更新它们,我们将创建一个名为`board` HashMap
2. 为了将正确的棋子存储在正确的正方形中并根据玩家的移动来更新它们,我们将创建一个名为`board``HashMap`
```py
HashMap board = new HashMap<String, String>();
```
HashMap 的键将包含正方形的索引,而值将是正方形将保留的片段。 我们将使用一个字符串来表示一块特定的作品,该字符串将根据作品的名称包含一个字母。 例如,K 代表国王,B 代表主教。 我们通过使用大写和小写字母来区分白色和黑色部分。 大写字母代表白色,小写字母代表黑色。 例如,“K”代表白国王,“b”代表黑主教`board['e7'] = "P"`表示索引为`'e7'`的盒子当前有一个白色棋子。
`HashMap`的键将包含正方形的索引,而值将是正方形将保留的片段。 我们将使用一个字符串来表示一块特定的作品,该字符串将根据作品的名称包含一个字母。 例如,`K`代表王,`B`代表相。 我们通过使用大写和小写字母来区分白色和黑色部分。 大写字母代表白色,小写字母代表黑色。 例如,`K`代表白王,`b`代表黑相`board['e7'] = "P"`表示索引为`'e7'`的盒子当前有一个白色棋子。
3. 现在,让我们将它们放置在初始位置。 为此,我们需要定义`initializeBoard()`方法,如下所示:
......@@ -971,7 +971,7 @@ HashMap 的键将包含正方形的索引,而值将是正方形将保留的片
}
```
在前面的方法中,我们使用一个简单的嵌套循环通过从 a 到 h 的所有行以及从 1 到 8 的所有列进行遍历,使用空白字符串初始化哈希地图板的所有索引。 如“步骤 2”中所述,将其放置在其初始位置上。 为了确保在初始化开发板时重新绘制 UI,我们将整个分配放在`setState()`中。
在前面的方法中,我们使用一个简单的嵌套循环通过从`a``h`的所有行以及从 1 到 8 的所有列进行遍历,使用空白字符串初始化哈希地图板的所有索引。 如“步骤 2”中所述,将其放置在其初始位置上。 为了确保在初始化开发板时重新绘制 UI,我们将整个分配放在`setState()`中。
4. 屏幕启动后,板将被初始化。 为了确保这一点,我们需要覆盖`initState()`并从那里调用`initializeBoard()`
......@@ -1042,7 +1042,7 @@ Widget mapImages(String squareName) {
}
```
在前面的函数中,我们构建一个与矩形中所含件名相对应的开关盒块。 我们使用哈希图在特定的正方形中找到片段,然后返回相应的图像。 例如,如果将`a1`的值传递到`squareName`中,并且哈希图板具有与键值`a1`对应的值“P”,则白色 Pawn 的图像将存储在`imageToDisplay`中 变量。
在前面的函数中,我们构建一个与矩形中所含件名相对应的开关盒块。 我们使用哈希图在特定的正方形中找到片段,然后返回相应的图像。 例如,如果将`a1`的值传递到`squareName`中,并且哈希图板具有与键值`a1`对应的值`P`,则白兵的图像将存储在`imageToDisplay`中 变量。
请注意,在 64 个棋盘格正方形中,只有 32 个包含棋子。 其余将为空白。 因此,在哈希表`board`中,将存在没有值的键。 如果`squareName`没有片段,则将其传递给`imageToDisplay`变量,该变量将只有一个空容器。
......@@ -1164,7 +1164,7 @@ Widget getImage(String squareName) {
}
```
在前面的函数中,我们首先将特定正方形的图像包装在`Draggable`中。 此类用于感测和跟随屏幕上的拖动手势。 child 属性用于指定要拖动的窗口小部件,而反馈内部的窗口小部件用于跟踪手指在屏幕上的移动。 当拖动完成并且用户抬起手指时,目标将有机会接受所携带的数据。 由于我们正在源和目标之间移动,因此我们将添加`Draggable`作为`DragTarget`的子代,以便可以在源和目标之间移动小部件。 `onWillAccept`设置为 true,以便可以进行所有移动。
在前面的函数中,我们首先将特定正方形的图像包装在`Draggable`中。 此类用于感测和跟随屏幕上的拖动手势。 `child`属性用于指定要拖动的窗口小部件,而反馈内部的窗口小部件用于跟踪手指在屏幕上的移动。 当拖动完成并且用户抬起手指时,目标将有机会接受所携带的数据。 由于我们正在源和目标之间移动,因此我们将添加`Draggable`作为`DragTarget`的子代,以便可以在源和目标之间移动小部件。 `onWillAccept`设置为`true`,以便可以进行所有移动。
可以修改此属性,以使其具有可以区分合法象棋动作并且不允许拖动非法动作的功能。 放下片段并完成拖动后,将调用`onAccept``moveInfo`列表保存有关拖动源的信息。 在这里,我们调用`refreshBoard()`,并传入`from``to`的值,以便屏幕可以反映运动。 至此,我们完成了向用户显示初始棋盘的操作,并使棋子可以在盒子之间移动。
......@@ -1204,9 +1204,9 @@ String getPositionString(String move) {
在前面的方法中,我们将`move`作为参数,它是`from``to`变量的串联。 接下来,我们为棋盘的当前状态创建 FEN 字符串。 创建 FEN 字符串背后的逻辑是,我们遍历电路板的每一行并为该行创建一个字符串。 然后将生成的字符串连接到最终字符串。
让我们借助示例更好地理解这一点。 考虑一个`rnbqkbnr/pp1ppppp/8/1p6/8/3P4/PPP1PPPP/RNBQKBNR w KQkq - 0 1`的 FEN 字符串。 在此,每行可以用八个或更少的字符表示。 特定行的状态通过使用分隔符“/”与另一行分开。 对于特定的行,每件作品均以其指定的符号表示,其中“P”表示白色典当,`b`表示黑色 Bishop。 每个占用的正方形均由件符号明确表示。 例如,`PpkB`指示板上的前四个正方形被白色棋子,黑色棋子,黑色国王和白色主教占据。 对于空盒子,使用整数,该数字表示可传染的空盒子的数量。 注意示例 FEN 字符串中的`8`。 这表示该行的所有 8 个正方形均为空。 `3P4`表示前三个正方形为空,第四个方框被白色棋子占据,并且四个正方形为空。
让我们借助示例更好地理解这一点。 考虑一个`rnbqkbnr/pp1ppppp/8/1p6/8/3P4/PPP1PPPP/RNBQKBNR w KQkq - 0 1`的 FEN 字符串。 在此,每行可以用八个或更少的字符表示。 特定行的状态通过使用分隔符“/”与另一行分开。 对于特定的行,每件作品均以其指定的符号表示,其中`P`表示白兵,`b`表示黑相。 每个占用的正方形均由件符号明确表示。 例如,`PpkB`指示板上的前四个正方形被白色棋子,黑色棋子,黑色国王和白色主教占据。 对于空盒子,使用整数,该数字表示可传染的空盒子的数量。 注意示例 FEN 字符串中的`8`。 这表示该行的所有 8 个正方形均为空。 `3P4`表示前三个正方形为空,第四个方框被白色棋子占据,并且四个正方形为空。
`getPositionString()`方法中,我们迭代从 8 到 1 的每一行,并为每行生成一个状态字符串。 对于每个非空框,我们只需在`'s'`变量中添加一个表示该块的字符。 对于每个空框,当找到非空框或到达行末时,我们将 count 的值增加 1 并将其连接到`'s'`字符串。 遍历每一行后,我们添加“/”以分隔两行。 最后,我们通过将生成的`'s'`字符串与`w KQkq - 0 1`串联来生成位置字符串。 然后,我们通过将`jsonEncode()`与键值对结合使用来生成所需的 JSON 对象
`getPositionString()`方法中,我们迭代从 8 到 1 的每一行,并为每行生成一个状态字符串。 对于每个非空框,我们只需在`'s'`变量中添加一个表示该块的字符。 对于每个空框,当找到非空框或到达行末时,我们将`count`的值增加 1 并将其连接到`'s'`字符串。 遍历每一行后,我们添加“/”以分隔两行。 最后,我们通过将生成的`'s'`字符串与`w KQkq - 0 1`串联来生成位置字符串。 然后,我们通过将`jsonEncode()`与键值对结合使用来生成所需的 JSON 对象
2. 我们使用“步骤 1”的“步骤 1”中的`from``to`变量来保存用户的当前移动。 我们可以通过在`refreshBoard()`方法中添加两行来实现:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册