dart dart2 区别_Dart和PHP:传统动物猜谜游戏

dart dart2 区别

回到我使用BASIC在Apple II上学习编程时,有一个Animal Guess游戏。 该游戏是一个非常原始的AI游戏:计算机尝试询问一些“是/否”问题,并从用户那里收到答案。 根据答案,它可能会问更多的是/否问题,直到试图猜测动物为止。

在本教程中,我们将学习如何使用PHP作为后端以及Dart作为前端来重新激活该程序。 当然,将使用数据库来存储所有有关动物的问题和猜测。

完整的代码已上传到Github。 您可以从这里克隆它。

数据库设置

该程序的数据库结构很简单。 我们只需要一张桌子:

CREATE TABLE `animal` (
  `id` int(11) NOT NULL,
  `question` varchar(140) DEFAULT NULL,
  `y_branch` int(11) DEFAULT NULL,
  `n_branch` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

id用于识别每个问题/猜测; question是要问的问题或要提示的猜测; 当用户对问题回答是或否时, y_branchn_branch标识问题ID。 特别是,如果这两个字段都为“ -1”,则意味着不再有其他问题要问(程序已经进入猜测阶段)。

SQL结构和初始数据(一个问题和两个动物)可以在animal.sql文件中找到。

后端

由于后端相对简单,因此我将使用纯PHP(带有PDO)。 这些文件位于存储库中的server目录下。 服务器基本上具有两个功能:

  1. 通过ID提出问题或提示猜测;
  2. 用用户的输入拆分一个带有新问题和新猜测的节点;

我们将看一下getquest函数:

<?php

    require_once 'pdo.php';

    $id=filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);

    if(!$id)
        $id=1;

    $res=$cn->prepare('select * from animal where id = :id');
    $res->bindParam(':id', $id);
    $res->execute();

    $r=$res->fetch();

    $ret=array();
    $ret['q']=$r[1];
    $ret['y']=$r[2];
    $ret['n']=$r[3];

    setExtraHeader();

    echo json_encode($ret);
    ?>

在此get.php文件中,我们包括一个pdo.php文件来设置数据库连接。 然后我们处理输入并进行查询。 最后,我们将结果输出到前端(在本例中为Dart应用)。

这里需要注意的几件事:

  1. 返回给Dart应用的所有结果均应为JSON格式。 因此,我们使用json_encode函数对数组进行编码。
  2. 在实际返回结果之前,我们设置了一些额外的HTTP标头以启用CORS 。 尽管我们所有文件实际上都是在同一台计算机上,但Dart应用程序和后端实际上是在两个不同的域上运行。 如果没有额外的头,则从前端到后端的调用将失败。 setExtraHeader函数也在pdo.php定义。

前端

通过HTML5,JavaScript和其他第三方库,非常方便(或复杂?)前端Web编程。 它只需要更加结构化即可。

在本教程中,我们将使用Google的Dart作为前端开发工具。

安装

要获取Dart IDE,请访问 https://www.dartlang.org并下载适合您平台的软件包。 安装非常简单。 或者, 下载Webstorm ,其中包含本机Dart支持,并且比基于Eclipse的Dart Editor更稳定,性能更高。

Dart刚刚发布了其稳定版本,并摘下了其长期使用的“ BETA”帽子,但它发展Swift。 在撰写本文时,我正在使用Dart编辑器和SDK版本1.0.0_r30188(STABLE)。

为了充分利用Dart提供的交互性,我们将使用新的Polymer库。

注意: Polymer取代了旧版Dart中的web_ui库。 像Dart一样,Polymer也正在Swift发展。 我在该程序中使用的是0.9.0 + 1版。 某些语法和功能在将来的版本中可能会有所不同。

在开发前端时,Polymer提供了一些有用的功能,例如自定义HTML元素,双向数据绑定,条件模板,异步远程函数调用等。所有这些功能都将在此程序中使用。

创建一个聚合物应用程序

启动Dart IDE,然后选择“文件|新应用程序”。 确保选择“ Web应用程序(使用聚合物库)”作为应用程序类型。

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

该向导将创建应用程序目录并设置所有必要的依赖项。 当我们选择“生成示例内容”时,它还将创建一些示例文件。 我们可以删除除pubspec.yaml之外的所有这些示例文件。

右键单击pubspec.yaml文件,然后从菜单中选择Pub Get 。 这将有助于安装Dart / Polymer应用程序的所有必需库。

一个典型的Polymer应用程序至少包含3个文件:

  1. 一个HTML文件作为应用程序入口点。 在这种情况下: web/animalguess.html 。 通常,在此文件中,我们将为HTML文件设置基本结构,并必须实例化自定义HTML元素。
  2. 一个HTML文件,用于定义自定义HTML元素,布局,该元素的脚本等。在这种情况下: web/animalguessclass.html
  3. 实现该自定义HTML元素功能的DART文件。

让我们讨论每个文件的关键点。

animalguess.html

animalguess.html文件定义了应用程序的整体布局。 这是一个符合HTML5的文件,其中包含所有常规的HEAD,TITLE,LINK,SCRIPT,META元素以及自定义HTML元素标签。

<!DOCTYPE html>

    <html>
    <head>
    <meta charset="utf-8">
    <title>Welcome to Animal Guess Game!</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/animal.css">

    <!-- import the underlying class -->
    <link rel="import" href="animalguessclass.html">
    <script type="application/dart">import 'package:polymer/init.dart';</script>
    <script src="packages/browser/dart.js"></script>
    </head>
    <body>
          <div class="container">
            <h1>Welcome to the legacy Animal Guess Game!</h1>
            <p><em>Revitalized with PHP and Dart!</em></p>
          </div>
          <hr>
        <animal-guess></animal-guess>
    </body>
    </html>

<head></head>部分的大部分时间里,我们真的不需要进行任何更改。 对于此应用程序,我仅更改了两个CSS链接以链接到Bootstrap CSS和我进一步定制CSS。

在BODY部分中,我们包括了自定义HTML元素<animal-guess> 。 此元素在animalguessclass.html定义,并通过<link rel="import" href="animalguessclass.html">语句<link rel="import" href="animalguessclass.html">

animalguessclass.html和自定义元素

此文件定义自定义HTML元素的布局,模板,行为。 但是,用于实现该行为的实际代码通常是在单独的DART文件( animalguessclass.dart )中定义的。

<polymer-element name="animal-guess"> 
        <template>

            <div class="container">    
              <template if="{{!gameinprogress}}">
                  <h3>Let's get started!</h3>
                  <button on-click="{{newGame}}">Click me</button>
              </template>

          ...
              <template if="{{gameinprogress}}">
                  <div class="row">
                    <div class="col-md-6">{{qid}}. {{question}}</div>
                        <template if="{{!reachedend}}">
                            <div class="col-md-6">
                                  <a href="#" on-click="{{YBranch}}">Yes</a>&nbsp;&nbsp;<a href="#"
                            on-click="{{NBranch}}">No</a>
                            </div>
                        </template>
                      </div>
              </template>
        ...          
        </template>
        <script type="application/dart" src="animalguessclass.dart"></script>
    </polymer-element>

上面的摘录显示了Polymer元素HTML文件的基本结构。

<polymer-element name="animal-guess"></polymer-element>来定义元素。 请注意name属性。 它具有与animalguess.html"animal-guess" )中使用的值相同的值。

有条件模板实例化。 例如:

<template if="{{!gameinprogress}}">
          <h3>Let's get started!</h3>
        <button on-click="{{newGame}}">Click me</button>
      </template>

除非gameinprocess为false,否则不会呈现<template></template>之间HTML代码。 gameinprogress是一个变量,稍后将进行阐述。

另外,请注意,我们已经将按钮元素的click事件挂接到了事件处理程序( "newgame" )上。 我们稍后还将讨论。

一般来说,此HTML文件与传统HTML文件或HTML模板没有什么不同。 我们可以在此文件中使用各种HTML元素。

注意:可以使用单选按钮。 但是,还有一些与值的绑定有关的问题。 因此,在此实现中,我们仅使用文本框进行输入。 可能存在与其他类型的表单控件的数据绑定有关的问题,但是我们不在此讨论。

此外,在此文件中,我们声明将使用animalguessclass.dart作为此元素的脚本。

animalguessclass.html可以在web目录中找到animalguessclass.html的完整代码。

动物猜测类

此文件是此应用程序的驱动程序。 它具有驱动程序行为的所有逻辑。 让我们看一些关键部分。

import 'package:polymer/polymer.dart';
import 'dart:html';
import 'dart:convert';

@CustomTag('animal-guess')
class AnimalGuess extends PolymerElement {
  @published bool gameinprogress=false;
  @published String question='';
  @published String myguess='';
  @published int qid=1;
  int yBranch;
  int nBranch;
  ...

  AnimalGuess.created() : super.created() {
    // The below 2 lines make sure the Bootstrap CSS will be applied
    var root = getShadowRoot("animal-guess");
    root.applyAuthorStyles = true;
  }

  void newGame() {
    gameinprogress=true;
    win=false;
    lost=false;
    reachedend=false;
    qid=1;
    getQuestionById(qid);
  }

  void getQuestionById(qid)
  {
    var path='http://animal/get.php?id=$qid';
    var req=new HttpRequest();
    req..open('GET', path)
      ..onLoadEnd.listen((e)=>requestComplete(req))
      ..send('');
  }

  void requestComplete(HttpRequest req)
  {
    if (req.status==200)
    {
      Map res=JSON.decode(req.responseText);
      myguess=res['q'];
      yBranch=res['y'];
      nBranch=res['n'];

      if (yBranch==-1 && nBranch==-1) // No more branches and we have reached the "guess"
      {
        question='Is it a/an $myguess?';
      }
      else
      {
        question=myguess;
      }
    }
  }
}

前3个import语句导入此脚本中使用的必要库。 使用Polymer和DOM时,前两个是必需的,而解码JSON时,我们也需要第三个。 要查看其他软件包和库,请参阅API参考软件包存储库

@CustomTag('animal-guess')定义了我们将使用的自定义标签。 它具有与animalguess.htmlanimalguessclass.html出现的名称相同的名称。

在类定义中,我们看到一些变量声明。 Polymer使用@published关键字声明一个“公共”变量(例如gameinprogress标志,该标志指示游戏是否已启动并用于确定要显示哪个模板),并且可以在脚本以及相关的html文件中进行访问( animalguessclass.html )。 这样,我们创建了“双向”数据绑定。

其余的是函数声明。 大多数功能将是上述animalguess.htmlon-click ”事件的“事件处理程序”。 其他类型的事件处理程序也可用。

注意事项:

  • 在类构造函数中,我们做了一个技巧,以确保可以将Bootstrap CSS应用于我们的自定义HTML标记(“ animal-guess ”)。 本文中的问题在Stackoverflow上进行了阐述。 基本上,Bootstrap“不了解ShadowDOM,而是尝试使用全局选择器从DOM中获取节点。” 但是在Polymer中,几乎要强制我们使用自定义元素,并且存在Shadow DOM。 因此,“转变”只是为了确保我们创建的ShadowDOM可与Bootstrap配合使用并具有我们想要CSS样式。
  • 回调函数( requestComplete )连接到HttpRequest对象。 使用的语法在Polymer中是新的,称为“链接”方法调用。 它不同于单点符号,并且使用两个点。 它等效于以下3条语句:
req.open(...);
req.onLoadEnd(...)...;
req.send(...);
  • requestComplete函数中,我们首先测试HTTP状态代码(200表示一切正常),然后使用Map类型变量存储解码后的JSON对象。 该变量将具有一个精确的“键值”对,作为从我们的远程服务器返回的JSON结果。 在我们的案例中,后端“远程”服务器位于同一台计算机上(在80端口上运行),并且在Dart中启动时,该应用程序将在3030端口上运行。 因此,从这个意义上讲,它们位于两个不同的域中,并且必须在返回的HTTP响应中显示CORS标头。

下面是计算机耗尽问题但做出错误猜测时的屏幕截图。 然后它提示输入一个新问题,以区分其猜测和用户的动物:

至此,该应用程序已经可以运行:后端提供数据,前端提供应用程序逻辑和表示。 至少可以完成一项改进:使用单选按钮表单控件来接收新问题的答案并限制用户的输入。 我留给你。

部署成为独立应用程序

当前程序只能在Dart自己的浏览器中运行(高度定制的基于Chrome的浏览器,支持Dart解释器–下载Dart SDK时会自动下载)。 为了使应用程序独立,我们可以将Dart应用程序编译为JavaScript。

为此,请在项目根目录中单击“ build.dart ”文件,然后选择“ Tools | Pub Build 。经过一些处理后,新的“ build ”目录将出现在项目根目录中,其中包含运行所需的所有文件它可以作为一个独立的应用程序。我们只需将所有这些文件复制到一个站点中,它将可以正常运行。

结论

在本教程中,我们使用现代技术(数据库,Dart和PHP)重新激活了旧版的Guess Animal AI游戏。 本教程的目的是演示所有部分的无缝集成,并以结构化的方式制作有用的富Web应用程序。

如果您有任何反馈或疑问,请在下面的评论中留下,我会尽快解决。 如果您发现本文有趣,并希望扩展本文的范围,请与您的朋友和同事分享,以便我们评估您的兴趣并做出相应的计划。

翻译自: https://www.sitepoint.com/dart-php-legacy-animal-guess-game/

dart dart2 区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值