﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-逖靖寒的世界</title><link>http://www.cnblogs.com/gpcuster/</link><description>Share my world.
Share your viewpoint.</description><language>zh-cn</language><lastBuildDate>Sun, 07 Sep 2008 14:13:19 GMT</lastBuildDate><pubDate>Sun, 07 Sep 2008 14:13:19 GMT</pubDate><ttl>60</ttl><item><title>了解博客园仿真足球竞赛平台的所有内部运行细节</title><link>http://www.cnblogs.com/gpcuster/archive/2008/09/01/1280979.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Mon, 01 Sep 2008 02:18:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/09/01/1280979.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1280979.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/09/01/1280979.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1280979.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1280979.html</trackback:ping><description><![CDATA[摘要: <img src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg" class="desc_img"/>
平台的内部逻辑处理的代码公布。&nbsp;&nbsp;<a href='http://www.cnblogs.com/gpcuster/archive/2008/09/01/1280979.html'>阅读全文</a><img src ="http://www.cnblogs.com/gpcuster/aggbug/1280979.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42134/" target="_blank">[新闻]JavaScript将成Silverlight的最大对手?</a>]]></description></item><item><title>博客园仿真足球竞赛平台更新信息</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/30/1280342.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Sat, 30 Aug 2008 14:32:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/30/1280342.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1280342.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/30/1280342.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1280342.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1280342.html</trackback:ping><description><![CDATA[<p></p> <p>关于本平台的使用以及编写球队的基本教程已经更新完毕，下面我补充说明一些相关内容和更新说明。</p> <p>&nbsp;</p> <h4>1 平台更新说明</h4> <p>大家启动博客园仿真足球竞赛平台以后，在“设置”-&gt;“平台设置”中可以看到：</p> <p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/1b77e6fccb88_9684/1_2.jpg"><img style="border: 0px none ;" alt="1" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/1b77e6fccb88_9684/1_thumb.jpg" width="322" border="0" height="256"></a> </p> <p>原先“通信IP地址”是不可以修改的，这样会对机器有多个可用的网络适配器的用户造成麻烦。</p> <p>现在平台将自动列出所有可用的网络适配器地址出来，你可以根据自己的实际情况来选择。（虽然你可以直接在文本框中输入地址，但是不建议这么做。） </p> <p><font color="#ff8000">thanks to </font><a href="http://space.cnblogs.com/ria"><font color="#ff8000">风中独火</font></a></p> <p>&nbsp;</p> <p>大家启动博客园仿真足球竞赛平台以后，可以看到原先的一个比较大的“启动平台”按钮变小了，同时下面出现了一个“断开连接”按钮：</p> <p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/1b77e6fccb88_9684/2_2.jpg"><img style="border: 0px none ;" alt="2" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/1b77e6fccb88_9684/2_thumb.jpg" width="90" border="0" height="78"></a> </p> <p>大家启动比赛或者启动调试以后，如果希望结束比赛或者是结束调试，然后重新开始的话，以前的做法只能是重启程序。</p> <p>现在，你只需要点击“断开连接”即可恢复到刚刚启动程序时候的状态。</p> <p><font color="#ff8000">thanks to </font><a href="http://space.cnblogs.com/group/coderzh/"><font color="#ff8000">CoderZh</font></a></p> <p>&nbsp;</p> <p>修正了平台PhysicalModel.dll中一些逻辑判断的错误：</p> <p>守门员扑球条件的判断。</p> <p>踢球命令角度的越界处理。</p> <p>转身命令角度的越界处理。</p> <p>&nbsp;</p> <p>&nbsp;</p> <h4>2 配置文件说明</h4> <p>&nbsp;</p> <p>平台的配置文件说明</p> <p>在平台的文件目录下，有一个“Setting Files”文件夹：</p> <p>GameSettings.xml：这个文件指定比赛平台相应信息</p> <blockquote><p><font color="#0000ff">&lt;CanDropBall&gt;true&lt;/CanDropBall&gt; <font color="#000000">比赛的时候是否可以用鼠标掷球</font><br>&lt;GameCycle&gt;3000&lt;/GameCycle&gt; <font color="#000000">比赛的总周期数<br></font>&lt;LogPlaySpeed&gt;20&lt;/LogPlaySpeed&gt; <font color="#000000">录像的播放速度<br></font>&lt;RecordLog&gt;false&lt;/RecordLog&gt; <font color="#000000">是否录像<br></font>&lt;CycleTime&gt;100&lt;/CycleTime&gt; <font color="#000000">球员思考的时间（毫秒）<br></font>&lt;UseVisionError&gt;false&lt;/UseVisionError&gt; <font color="#000000">是否使用视觉误差<br></font>&lt;UseMovementError&gt;false&lt;/UseMovementError&gt; </font><font color="#000000">是否使用运动误差</font></p></blockquote> <p>ServerSettings.xml：这个文件指定平台的连接设置</p> <blockquote><font color="#0000ff">&lt;ServerPortNum&gt;5001&lt;/ServerPortNum&gt; <font color="#000000">平台的连接端口号</font></font><br><font color="#0000ff">&lt;ServerIPAddress&gt;192.168.23.1&lt;/ServerIPAddress&gt; <font color="#000000">平台的IP地址</font></font><br><font color="#0000ff">&lt;ShowConnectPrompt&gt;true&lt;/ShowConnectPrompt&gt; </font><font color="#000000">是否提示平台的连接地址和端口号</font></blockquote><p> </p><p>RuleSettings.xml：这个文件指定平台的比赛规则设置。</p> <p>各个变量的具体命名就可以知道。我这里就不重复了。</p> <p><font color="#ff0000">我们可以通过修改这里的值来自己定义规则，方便测试球队。</font></p> <p>&nbsp;</p> <p>球队的配置文件说明</p> <p>在球队的目录下，同样有一个“Setting Files”文件夹：</p> <p>FieldSettings.xml：这个文件指定平台的场地规格（平台没有提供这个文件）</p> <p>RuleSettings.xml：这个文件指定平台的规则</p> <p>ServerSettings.xml：这个文件指定平台的连接设置</p> <p><font color="#ff0000">注意：如果没有这个文件夹或缺少其中的任意一份文件，只要你启动球队，就会自动帮你生成。</font></p> <p><font color="#ff0000">这里的配置文件是给咱们编写球队的人看的。修改这些文件中的值并不会让平台按照你的想法去执行，这些文件应该和平台的配置文件保持一致。如果平台的配置文件有变更，请用平台的配置文件替换球队的相应配置文件。</font></p> <p><font color="#ff0000">推荐的做法是：不要修改这些文件，除了在ServerSettings.xml中指定平台的端口号和IP地址。</font></p> <p>&nbsp;</p> <p>&nbsp;</p> <p><a href="http://space.cnblogs.com/group/cnblogsSoccer">博客园仿真足球交流小组</a> </p><p><a href="http://space.cnblogs.com/group/topic/4424/">相关资源下载</a> </p><p><a href="/gpcuster/category/151459.html">相关文章</a></p><img src ="http://www.cnblogs.com/gpcuster/aggbug/1280342.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42133/" target="_blank">[新闻]没有谷歌就活不下去的四个网站</a>]]></description></item><item><title>仿真足球队的整体的策略简单实现</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/29/1279173.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Fri, 29 Aug 2008 01:56:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/29/1279173.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1279173.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/29/1279173.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1279173.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1279173.html</trackback:ping><description><![CDATA[摘要: <img src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg" class="desc_img"/>
在上一篇文章中，我们已经基于CSharp球队模板实现了一个最快截球。 在这篇文章中，我们将以这个球队代码为基础，在他上面添加一些简单的策略，让其成为一个更加完整的示例。&nbsp;&nbsp;<a href='http://www.cnblogs.com/gpcuster/archive/2008/08/29/1279173.html'>阅读全文</a><img src ="http://www.cnblogs.com/gpcuster/aggbug/1279173.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42132/" target="_blank">[新闻]Google 10周岁生日</a>]]></description></item><item><title>仿真足球最快截球的设计和实现</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/28/1278365.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Thu, 28 Aug 2008 02:11:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/28/1278365.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1278365.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/28/1278365.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1278365.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1278365.html</trackback:ping><description><![CDATA[<p>在前面的文章中，我们已经将整个平台的流程和基本命令的使用讲解完毕了。在这一篇文章中，我们将要讲解编写自己的球队中最为基础，也是最为重要的一个部分。截球。</p> <p>&nbsp;</p> <p><strong>什么是截球？</strong></p> <p>大家自己在踢足球的时候，你的队友给你传一个球过来，大部分的时候你需要跑动才能将球拿到。但是，如果拿到球，这个时候你需要更加球的速度和自己的经验来判断球未来的位置，然后向你判断的那个位置去跑，这样才能拿到球。在这个过程中，你对球未来位置的判断，以及跑向这个位置并最终将球得到，就是我们现在所说的截球。</p> <p>&nbsp;</p> <p><strong>截球有哪些方式？</strong></p> <p>截球的方式有很多，基本上可以概括为3类：简单截球，最快截球和战略截球。</p> <p>&nbsp;</p> <p>简单截球：</p> <p>咱们可以<a href="http://files.cnblogs.com/gpcuster/%E7%AE%80%E5%8D%95%E6%88%AA%E7%90%83%E6%BC%94%E7%A4%BA.rar" target="_blank">下载录像</a>来观看实际的运行效果（该录像文件需要在平台中打开）。</p> <p>简单截球的实现原理很简单：</p> <p><font color="#0080ff">判断自己的身体朝向是否朝着足球？如果不是，转身朝向足球；如果是，想前奔跑。</font></p> <p>实现代码如下：</p> <div> <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// 简单截球的实现</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;param name="agent"&gt;要去截球的机器人&lt;/param&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;param name="ball"&gt;足球&lt;/param&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;截球的命令&lt;/returns&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">static</span> Command Dash2Ball(Agent agent, Ball ball)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">{</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    Vector2f tempPos = ball.Pos - agent.Pos;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Command command = <span style="color: rgb(0, 0, 255);">new</span> Command();</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">if</span> (Math.Abs(tempPos.GetDirection() - agent.Dir) &lt; 10)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        command.CType = CommandType.Dash;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        command.Parameter1 = RuleSettings.Instance.MaxDashVel;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 0, 255);">else</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        command.CType = CommandType.Turn;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        command.Parameter1 = tempPos.GetDirection();</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 0, 255);">return</span> command;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">}</pre></div></div>
<p>简单截球的示意图如下：</p>
<p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/238dd5d6897c_9C5E/p1_2.jpg"><img style="border-width: 0px;" alt="p1" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/238dd5d6897c_9C5E/p1_thumb.jpg" width="644" border="0" height="484"></a> </p>
<p>大家可以看出，因为<font color="#ff0000">没有对足球未来的位置进行判断，所以说在实际的截球过程中，会走不少弯路</font>。</p>
<p>&nbsp;</p>
<p>最快截球：</p>
<p>咱们可以<a href="http://files.cnblogs.com/gpcuster/%E6%9C%80%E5%BF%AB%E6%88%AA%E7%90%83%E6%BC%94%E7%A4%BA.rar" target="_blank">下载录像</a>观看实际的运行效果（该录像文件需要在平台中打开）。</p>
<p>最快截球的示意图如下：</p>
<p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/238dd5d6897c_9C5E/p2_2.jpg"><img style="border-width: 0px;" alt="p2" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/238dd5d6897c_9C5E/p2_thumb.jpg" width="644" border="0" height="484"></a> </p>
<p>大家可以看出，因为<font color="#ff0000">对足球未来的位置进行了判断，所以说在实际的截球过程中不会走弯路</font>。</p>
<p>&nbsp;</p>
<p>战略截球：</p>
<p>战略截球会对可以足球的未来位置进一步判断，从多个可以截球的位置中，选择出最适合自己的位置去截球（可能是最快的，也可能不是）。</p>
<p>这个属于更加高级的话题了，不属于我们这篇文章讨论的范围。</p>
<p>&nbsp;</p>
<p><strong>最快截球的设计原理</strong></p>
<p>大家一定听说过“狼追兔子”的问题。</p>
<p>啥？你没有听说过？问题描述是这样的“狼在兔子南边100米，看见兔子马上追。狼速10米每秒，兔子7米每秒。兔子往东跑，狼向着兔子跑，多久追到？”</p>
<p>简单吧。不过这可是一道小学生的数学奥赛题哦，对小学生来说还是有一定难度的。</p>
<p>我们的球员就是“狼”，足球就是“兔子”，其它的情景都是一样的。</p>
<p>我们用了一种非常简单，但是很直观实现：</p>
<p><font color="#0080ff">计算出足球运动X周期后的位置，判断我方的截球球员是否能在X周期内到达该位置。</font></p>
<p><font color="#0080ff">如果可以，则X周期就是最快截球需要的周期，同时足球在X周期后的位置就是我们的截球的位置。</font></p>
<p><font color="#0080ff">如果不可以，则让X+1，在回到最开始的判断。</font></p>
<p>实际的伪代码如下：</p>
<div>
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// 计算某一个球员的最快截球位置</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;param name="ball"&gt;需要截的球&lt;/param&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;param name="agent"&gt;需要去截球的队员&lt;/param&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;最快截球位置&lt;/returns&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 0, 255);">public</span> Vector2f PredictFastestInterceptBallPos(Ball ball, Agent agent)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">{</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 0, 255);">int</span> cycle = 0;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Vector2f pos = ball.Pos;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//判断球员能否在cycle周期内到达pos这个位置</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 0, 255);">while</span> (predictCycle2Pos(agent, pos) &gt; cycle)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        cycle++;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 128, 0);">//计算cycle周期后，足球的位置</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        pos = predictBallPos(cycle);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">return</span> pos;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">}</pre></div></div>
<p>&nbsp;</p>
<p><strong>最快截球的实现</strong></p>
<p>我们给的代码中，多加了一个功能，判断场上谁可以最快截球（相当于将场上所有球队的最快截球周期数都求解出来，然后去最快的那个）。</p>
<p>大家可以通过下载<a href="http://files.cnblogs.com/gpcuster/%E6%9C%80%E5%BF%AB%E6%88%AA%E7%90%83CSharp%E7%90%83%E9%98%9F.rar" target="_blank">最快截球c#球队</a>代码来了解具体的实现。</p>
<p>&nbsp;</p>
<p>在下一篇文章中，我们将向大家介绍基于最快截球的其它策略部分的编写：传球，射门，进攻跑位和防守跑位。</p>
<p>&nbsp;</p>
<p><a href="http://space.cnblogs.com/group/cnblogsSoccer">博客园仿真足球交流小组</a> 
</p><p><a href="http://space.cnblogs.com/group/topic/4424/">相关资源下载</a> 
</p><p><a href="/gpcuster/category/151459.html">相关文章</a></p><img src ="http://www.cnblogs.com/gpcuster/aggbug/1278365.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42131/" target="_blank">[新闻]祝Google 10周岁生日快乐</a>]]></description></item><item><title>深入理解整个比赛的执行流程</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/27/1277335.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Wed, 27 Aug 2008 01:50:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/27/1277335.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1277335.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/27/1277335.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1277335.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1277335.html</trackback:ping><description><![CDATA[<p>前面的一系列文章分别为大家讲解了博客园仿真足球竞赛平台的各个部分的功能和原理。在这篇文章中，我将把综合先前讲解的内容，将整个比赛平台的内部执行流程展现给大家。</p> <p>&nbsp;</p> <p>咱们可以通过阅读下面的平台代码了解比赛平台的内部执行流程</p> <div> <div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// 让比赛平台执行一个仿真周期</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> RunOneCycle()</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">{</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//比赛周期数+1</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    _gameState.CurrentTime++;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 128, 0);">//判断比赛是否结束</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">if</span> (_gameState.CurrentTime &gt;= _gameState.EndTime)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        _gameState.IsEnd = <span style="color: rgb(0, 0, 255);">true</span>;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: rgb(0, 128, 0);">//给球队发送比赛结束的信息</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        Communicator.Instance.SentGameOverToTeams();</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 0, 255);">return</span>;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 128, 0);">//判断是否进球，如果进球，重新开球</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">if</span> (_wm.ball.State != BallState.Normal)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 128, 0);">//左队进球</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: rgb(0, 0, 255);">if</span> (_wm.ball.State == BallState.LeftGoal)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: rgb(0, 128, 0);">//左队得分加1</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">            _gameState.LeftSorce++;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: rgb(0, 128, 0);">//右队重新开球</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">            _wm.KickOff(TeamIndex.Right);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 128, 0);">//右队进球</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (_wm.ball.State == BallState.RightGoal)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: rgb(0, 128, 0);">//右队得分加1</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">            _gameState.RightSorce++;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">            <span style="color: rgb(0, 128, 0);">//左队重新开球</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">            _wm.KickOff(TeamIndex.Left);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//将场上的信息（WorldModel）发送给2个球队</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 128, 0);">//这里发送给右边球队的WorldModel会自动进行转化，使右边的球员认为自己也是左边的队伍</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//这么做的好处是编写球队的时候不需要考虑左右边的情况，只需要认为自己是左边的队伍即可。</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    Communicator.Instance.SentWorldModelToTeams(_wm);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    </pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 128, 0);">/**********************************************</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">    *                                             *</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">    * 这个时候球队接收到了平台发送过来的场上信息，*</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">    * 并开始思考，本周期应该执行什么命令。        *</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"><span style="color: rgb(0, 128, 0);">    *                                             *</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">    ***********************************************/</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&nbsp;</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//接收球队的命令决策</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 128, 0);">//如果某个球队的思考时间超时（球队的思考时间在“比赛设置”中设置），则忽略这个超时的球队，并认为他本周期不执行任何命令</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    Command[] teamsCommands = Communicator.Instance.GetCommandsFromTeams();</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    </pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//执行2支球队的命令，更新场上的信息（WorldModel）</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">int</span> i = 0; i &lt; teamsCommands.Length; i++)</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    {</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        ICommand command = CommandFactory.GetCommand(commands[i].CType);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 128, 0);">//更新球员的信息</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">        wm.agents[i].Success = command.Perform(wm, commands[i], i);</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    }</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    </pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 128, 0);">//更新足球的信息</span></pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">    wm.ball.DoMove();</pre><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);">}</pre></div></div>
<p>&nbsp;</p>
<p>这里有3个地方需要注意：</p>
<blockquote><ol>
<li>平台会自动转化发送给右边球队的场上信息，使得他的思考和自己在左边的队伍一致。所以说，我们编写代码的时候，可以始终认为自己是左边的球队。 
</li><li>平台将场上的信息发送给球队以后，会开始计时（在“比赛设置”中的“球员思考时间”），如果某个球队的思考超时，则本周期服务器将不会等待，直接认为这个球队本周期的所有球队都执行Stay的命令。 
</li><li>更新球员信息的<font color="#0000ff">command.Perform</font>函数和更新足球信息<font color="#0000ff">ball.DoMove</font>函数的实现在<a href="/gpcuster/archive/2008/08/26/1276409.html" target="_blank">上一篇文章</a>有介绍。</li></ol></blockquote>
<p>以上就是博客园仿真足球竞赛平台的内部执行流程。</p>
<p>&nbsp;</p>
<p>在下一篇文章中，我们将讲解最快截球的设计和实现。</p>
<p>&nbsp;</p>
<p><a href="http://space.cnblogs.com/group/cnblogsSoccer">博客园仿真足球交流小组</a> 
</p><p><a href="http://space.cnblogs.com/group/topic/4424/">相关资源下载</a> 
</p><p><a href="/gpcuster/category/151459.html">相关文章</a></p><img src ="http://www.cnblogs.com/gpcuster/aggbug/1277335.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42130/" target="_blank">[新闻]Google十年市值达1500亿美元 创造奇迹</a>]]></description></item><item><title>博客园仿真足球竞赛平台的物理模型以及球员命令的分析</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/26/1276409.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Tue, 26 Aug 2008 01:49:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/26/1276409.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1276409.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/26/1276409.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1276409.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1276409.html</trackback:ping><description><![CDATA[<p>在本文中，我将向大家介绍平台的物理模型（如场地的规格，角度的计算标准等等）以及球队的命令的分析（5种命令如何使用，效果如何）。</p> <p>&nbsp;</p> <p>我们可以根据下面这个图片来了解平台的比赛场地模型。</p> <p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/c20b62376d64_127B6/1_2.jpg"><img style="border-width: 0px;" alt="1" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/c20b62376d64_127B6/1_thumb.jpg" width="758" border="0" height="570"></a> </p> <p>平台的左上角是场上坐标的原点（0，0），在原点的右边是X轴的正方向，原点的下方是Y轴的正方向。</p> <p>角度的计算是按照上图中的r角的方向来的。（顺时针方向为正方向）</p> <p>被蓝色标记的区域是禁区（左边的没有标记出来）。</p> <p>&nbsp;</p> <p>在实际的编程中，我们可以通过调用<font color="#0000ff">CnblogsDotNetSDK.Settings.FieldSettings</font><font color="#000000">获得下面的一系列代表球场上规格的具体数值：</font></p> <div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的长度</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldLength;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的宽度</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldWidth;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 禁区的长度</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldPNZLength;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 禁区的宽度</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldPNZWidth;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 中场圆的半径</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldMidCircleRadius;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 球门的宽度</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldDoorWidth;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 球门的Y坐标（较小的）</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldDoorY1;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 球门的Y坐标（较大的）</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">double</span> FieldDoorY2;

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的左顶点位置</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Vector2f FieldLeftTopPos

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的右底点位置</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Vector2f FieldRightBottomPos

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的矩形区域</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Rectangle Field



<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的左半场区域</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Rectangle LeftField

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的右半场区域</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Rectangle RightField

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的左禁区区域</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Rectangle LeftPNZ

<span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 比赛场地的右禁区区域</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> Rectangle RightPNZ</pre></div>
<p>&nbsp;</p>
<p>下面，我们来看看球员可以执行的命令。</p>
<p>Stay：执行该命令的球队本周期不会作出反应（相当于无命令）</p>
<p>平台实现代码：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 执行Stay命令，这是一个空命令，什么也不做，Just stay；）</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="wm"&gt;场上的信息&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="command"&gt;命令参数&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="num"&gt;执行该命令的球员编号&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;命令是否执行成功&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">bool</span> Perform(WorldModel wm, Command command, <span style="color: rgb(0, 0, 255);">int</span> num)
{
    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;
}</pre></div>
<p>Turn：执行该命令的球员身体朝向指定的方向（由<font color="#0000ff">Command.Parameter1</font>指定），该命令的有效转身角度在[-180，180]之间。所以在一个周期内，你能转向任何你需要的角度。<strong>注意：这里是希望转身以后的角度，而不是转身的角度。</strong></p>
<p>平台实现代码：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 执行Turn命令。</span>
<span style="color: rgb(0, 128, 0);">/// 这个命令中只有Command.parameter1是有效的，代表该球员希望转身以后的角度。</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="wm"&gt;场上的信息&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="command"&gt;命令参数&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="num"&gt;执行该命令的球员编号&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;命令是否执行成功&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">bool</span> Perform(WorldModel wm, Command command, <span style="color: rgb(0, 0, 255);">int</span> num)
{
    <span style="color: rgb(0, 128, 0);">//确保转身后的角度在有效的范围内</span>
    <span style="color: rgb(0, 0, 255);">double</span> turnAng =AngleHelper.NormalizeAngle(command.Parameter1);

    wm.agents[num].Dir = turnAng;

    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;
}</pre></div>
<p>Dash：执行该命令的球员将在当前身体朝向的方向中前进或者后退一定的距离（由<font color="#0000ff">Command.Parameter1</font>指定），如果希望前进，则有效的距离在[0, RuleSettings.Instance.MaxDashVel]之间，如果希望后退（给的值是负数），则有效的距离在[RuleSettings.Instance.MinDashVel，0]之间。<strong>注意：这里移动的距离方向按照球员当前的身体朝向来的，这也是为什么要有Turn命令的原因。</strong></p>
<p>平台实现代码：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 执行Dash命令。可以让指定的球员在一个周期内向前或向后移动一定的距离</span>
<span style="color: rgb(0, 128, 0);">/// 这个命令中只有Command.parameter1是有效的，代表该球员希望获得的速度。</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="wm"&gt;场上的信息&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="command"&gt;命令参数&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="num"&gt;执行该命令的球员编号&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;命令是否执行成功&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">bool</span> Perform(WorldModel wm, Command command, <span style="color: rgb(0, 0, 255);">int</span> num)
{
    <span style="color: rgb(0, 0, 255);">double</span> dashVel = command.Parameter1;

    <span style="color: rgb(0, 128, 0);">//确保球员的速度不越界</span>
    <span style="color: rgb(0, 0, 255);">if</span> (dashVel &gt; RuleSettings.Instance.MaxDashVel)
    {
        dashVel = RuleSettings.Instance.MaxDashVel;
    }
    <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (dashVel &lt; RuleSettings.Instance.MinDashVel)
    {
        dashVel = RuleSettings.Instance.MinDashVel;
    }

    Vector2f dashPos = <span style="color: rgb(0, 0, 255);">new</span> Vector2f(dashVel, wm.agents[num].Dir, <span style="color: rgb(0, 0, 255);">true</span>) + wm.agents[num].Pos;

    <span style="color: rgb(0, 128, 0);">//球员出了球场，计算反弹后的位置</span>
    <span style="color: rgb(0, 0, 255);">if</span> (!FieldSettings.Instance.Field.IsInside(dashPos))
    {
        Line l = Line.MakeLineFromPositionAndAngle(wm.agents[num].Pos, wm.agents[num].Dir);

        Line[] ls = <span style="color: rgb(0, 0, 255);">new</span> Line[4];
        ls[0] =
            Line.MakeLineFromTwoPoints(FieldSettings.Instance.FieldLeftTopPos,
                                       <span style="color: rgb(0, 0, 255);">new</span> Vector2f(FieldSettings.Instance.FieldLength, 0));
        ls[1] =
            Line.MakeLineFromTwoPoints(<span style="color: rgb(0, 0, 255);">new</span> Vector2f(0, FieldSettings.Instance.FieldWidth),
                                       FieldSettings.Instance.FieldRightBottomPos);
        ls[2] =
            Line.MakeLineFromTwoPoints(FieldSettings.Instance.FieldLeftTopPos,
                                       <span style="color: rgb(0, 0, 255);">new</span> Vector2f(0, FieldSettings.Instance.FieldWidth));
        ls[3] =
            Line.MakeLineFromTwoPoints(<span style="color: rgb(0, 0, 255);">new</span> Vector2f(FieldSettings.Instance.FieldLength, 0),
                                       FieldSettings.Instance.FieldRightBottomPos);

        <span style="color: rgb(0, 0, 255);">double</span> minDis = 9999;
        Vector2f newPos = <span style="color: rgb(0, 0, 255);">new</span> Vector2f(wm.agents[num].Pos);

        <span style="color: rgb(0, 0, 255);">foreach</span> (Line line <span style="color: rgb(0, 0, 255);">in</span> ls)
        {
            Vector2f collidePos = l.GetIntersection(line);

            <span style="color: rgb(0, 0, 255);">if</span> (collidePos.GetDistanceTo(wm.agents[num].Pos) &lt; minDis)
            {
                newPos = collidePos;
                minDis = collidePos.GetDistanceTo(wm.agents[num].Pos);
            }
        }

        wm.agents[num].Pos = newPos;

        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }
    <span style="color: rgb(0, 0, 255);">else</span>
    {
        wm.agents[num].Pos = dashPos;

        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;
    }
}</pre></div>
<p>Kick：执行该命令的球员将给足球施加一个速度（Vector2f）。速度的大小由<font color="#0000ff">Command.Parameter1</font>决定，有效值的范围在[RuleSettings.Instance.MinKickBallVelocity，RuleSettings.Instance.MaxKickBallVelocity]之间，速度的方向由<font color="#0000ff">Command.Parameter2</font><font color="#000000">决定，有效的范围在[RuleSettings.Instance.MinKickBallAngle，RuleSettings.Instance.MaxKickBallAngle]之间。<strong>注意：球和球员之间的距离必须不大于RuleSettings.Instance.MaxKickBallDistance，如果多个人同时踢球，则给球的速度取这些速度的和（初中的2维向量相加）。</strong></font></p>
<p>平台实现代码：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 执行Dash命令。可以让指定的球员在本周期给足球添加一个速度</span>
<span style="color: rgb(0, 128, 0);">/// Command.parameter1 代表速度的大小</span>
<span style="color: rgb(0, 128, 0);">/// Command.parameter2 代表速度的方向</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="wm"&gt;场上的信息&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="command"&gt;命令参数&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="num"&gt;执行该命令的球员编号&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;命令是否执行成功&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">bool</span> Perform(WorldModel wm, Command command, <span style="color: rgb(0, 0, 255);">int</span> num)
{
    <span style="color: rgb(0, 128, 0);">//如果球员于足球的距离大于MaxKickBallDistance，则踢球失败</span>
    <span style="color: rgb(0, 0, 255);">if</span> (wm.agents[num].Pos.GetDistanceTo(wm.ball.Pos) &gt; RuleSettings.Instance.MaxKickBallDistance)
    {
        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 0, 255);">double</span> kickVelocity = command.Parameter1;

    <span style="color: rgb(0, 128, 0);">//确保踢球的角度在有效的范围内</span>
    <span style="color: rgb(0, 0, 255);">double</span> kickAngle = AngleHelper.NormalizeAngle(command.Parameter2);

    <span style="color: rgb(0, 128, 0);">//确保踢球的速度在有效的范围内</span>
    <span style="color: rgb(0, 0, 255);">if</span> (kickVelocity &gt; RuleSettings.Instance.MaxKickBallVelocity)
    {
        kickVelocity = RuleSettings.Instance.MaxKickBallVelocity;
    }
    <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (kickVelocity &lt; RuleSettings.Instance.MinKickBallVelocity)
    {
        kickVelocity = RuleSettings.Instance.MinKickBallVelocity;
    }

    wm.ball.Vel += <span style="color: rgb(0, 0, 255);">new</span> Vector2f(kickVelocity, kickAngle, <span style="color: rgb(0, 0, 255);">true</span>);

    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;
}</pre></div>
<p>Catch：执行该命令的球员将球的速度变为0，同时将在自己禁区中的非本队的球员朝X方向移除自己的禁区。<strong>注意：执行该命令的球员必须是1号，足球和球员直接的距离不能大于RuleSettings.Instance.MaxCatchBallDistance，并且球员在自己的禁区扑球一次以后，必须等球出了自己的禁区才能再次使用该命令。</strong></p>
<p>平台实现代码：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 扑球的命令类，可以让守门员在本周期把足球停止住，同时让对方的球员移出自己边的禁区</span>
<span style="color: rgb(0, 128, 0);">/// 球员在自己的禁区扑球一次以后，必须等球出了自己的禁区才能再次使用该命令</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="wm"&gt;场上的信息&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="command"&gt;命令参数&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;param name="num"&gt;执行该命令的球员编号&lt;/param&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;命令是否执行成功&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">bool</span> Perform(WorldModel wm, Command command, <span style="color: rgb(0, 0, 255);">int</span> num)
{
    <span style="color: rgb(0, 128, 0);">//只有守门员可以执行这个命令</span>
    <span style="color: rgb(0, 0, 255);">if</span> ((num % RuleSettings.Instance.AgentNum + 1) != RuleSettings.Instance.CatchNum)
    {
        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 128, 0);">//判断是否连续扑球</span>
    <span style="color: rgb(0, 0, 255);">if</span> ( (num &lt; RuleSettings.Instance.AgentNum &amp;&amp; !CanLeftTeamCatch) || !CanRightTeamCatch)
    {
        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 128, 0);">//判断扑球的距离是否合理</span>
    <span style="color: rgb(0, 0, 255);">if</span> (wm.ball.Pos.GetDistanceTo(wm.agents[num].Pos) &gt; RuleSettings.Instance.MaxCatchBallDistance)
    {
        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }

    Rectangle PNZ;
    <span style="color: rgb(0, 0, 255);">int</span> startIndex;
    <span style="color: rgb(0, 0, 255);">bool</span> left = <span style="color: rgb(0, 0, 255);">false</span>;
    
    <span style="color: rgb(0, 0, 255);">if</span> (num &lt; RuleSettings.Instance.AgentNum)
    {
        startIndex = RuleSettings.Instance.AgentNum;
        PNZ = FieldSettings.Instance.LeftPNZ;
        left = <span style="color: rgb(0, 0, 255);">true</span>;
    }
    <span style="color: rgb(0, 0, 255);">else</span>
    {
        startIndex = 0;
        PNZ = FieldSettings.Instance.RightPNZ;
        left = <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 128, 0);">//球必须在禁区中</span>
    <span style="color: rgb(0, 0, 255);">if</span> (!PNZ.IsInside(wm.ball.Pos))
    {
        <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 128, 0);">//让球停止运动</span>
    wm.ball.Stop();
    <span style="color: rgb(0, 128, 0);">//将对方的球员移除自己的禁区</span>
    <span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">int</span> i = startIndex; i &lt; startIndex + RuleSettings.Instance.AgentNum; i++)
    {
        <span style="color: rgb(0, 0, 255);">if</span> (PNZ.IsInside(wm.agents[i].Pos))
        {
            <span style="color: rgb(0, 0, 255);">if</span> (left)
            {
                wm.agents[i].Pos = <span style="color: rgb(0, 0, 255);">new</span> Vector2f(PNZ.PosRightBottom.X, wm.agents[i].Pos.Y);
            }
            <span style="color: rgb(0, 0, 255);">else</span>
            {
                wm.agents[i].Pos = <span style="color: rgb(0, 0, 255);">new</span> Vector2f(PNZ.PosLeftTop.X, wm.agents[i].Pos.Y);
            }
        }
    }

    <span style="color: rgb(0, 128, 0);">//不能连续扑球的设置</span>
    <span style="color: rgb(0, 0, 255);">if</span> (left)
    {
        CanLeftTeamCatch = <span style="color: rgb(0, 0, 255);">false</span>;
    }
    <span style="color: rgb(0, 0, 255);">else</span>
    {
        CanRightTeamCatch = <span style="color: rgb(0, 0, 255);">false</span>;
    }

    <span style="color: rgb(0, 0, 255);">return</span> <span style="color: rgb(0, 0, 255);">true</span>;

}</pre></div>
<p>以上就是球队的运动模型和命令分析。</p>
<p>&nbsp;</p>
<p>最后一项是足球的运动模型：</p>
<p>足球下一个周期的位置 = 这一个周期的位置 + 这一个周期的速度</p>
<p>足球下一个周期的速度 = 这一个周期的速度 * 速度的衰减系数（RuleSettings.Instance.BallDelayRate）</p>
<p>平台的实现代码如下：</p>
<div><pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"><span style="color: rgb(0, 128, 0);">/// &lt;summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// 让足球在当前的速度下运动一个周期</span>
<span style="color: rgb(0, 128, 0);">/// &lt;/summary&gt;</span>
<span style="color: rgb(0, 128, 0);">/// &lt;returns&gt;返回球的状态，通过球的状态，可以知道是否进球。&lt;/returns&gt;</span>
<span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> DoMove()
{
    <span style="color: rgb(0, 128, 0);">//如果球的速度过大，则让球的速度大小变为BallMaxVelocity，方向不变</span>
    <span style="color: rgb(0, 0, 255);">if</span> (_vel.GetLength() &gt; RuleSettings.Instance.BallMaxVelocity)
    {
        _vel.SetLength(RuleSettings.Instance.BallMaxVelocity);
    }

    Vector2f newPos = _pos + _vel;

    <span style="color: rgb(0, 128, 0);">//球到了左边球门中，右方进球</span>
    <span style="color: rgb(0, 0, 255);">if</span> (newPos.X &lt;= 0 &amp;&amp;
        newPos.IsBetweenY(FieldSettings.Instance.FieldDoorY1,
                          FieldSettings.Instance.FieldDoorY2))
    {
        _pos = newPos;
        _state = BallState.RightGoal;
        <span style="color: rgb(0, 0, 255);">return</span>;
    }
    <span style="color: rgb(0, 128, 0);">//球到了右边球门中，左方进球</span>
    <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (newPos.X &gt;= FieldSettings.Instance.FieldLength &amp;&amp;
             newPos.IsBetweenY(FieldSettings.Instance.FieldDoorY1,
                               FieldSettings.Instance.FieldDoorY2))
    {
        <span style="color: rgb(0, 0, 255);">this</span>.Pos = newPos;
        _state = BallState.LeftGoal;
        <span style="color: rgb(0, 0, 255);">return</span>;
    }

    <span style="color: rgb(0, 128, 0);">//球出了球场，计算反弹后的位置和速度(位置和速度取反)</span>
    <span style="color: rgb(0, 0, 255);">if</span> (!FieldSettings.Instance.Field.IsInside(newPos))
    {
        <span style="color: rgb(0, 0, 255);">if</span> (newPos.X &lt; 0)
        {
            newPos.X = -newPos.X;
            _vel.X = -_vel.X;
        }
        <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (newPos.X &gt; FieldSettings.Instance.FieldLength)
        {
            newPos.X = FieldSettings.Instance.FieldLength -
                       (newPos.X - FieldSettings.Instance.FieldLength);
            _vel.X = -_vel.X;
        }

        <span style="color: rgb(0, 0, 255);">if</span> (newPos.Y &lt; 0)
        {
            newPos.Y = -newPos.Y;
            _vel.Y = -_vel.Y;
        }
        <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (newPos.Y &gt; FieldSettings.Instance.FieldWidth)
        {
            newPos.Y = FieldSettings.Instance.FieldWidth -
                       (newPos.Y - FieldSettings.Instance.FieldWidth);
            _vel.Y = -_vel.Y;
        }
    }

    <span style="color: rgb(0, 128, 0);">//设置球的位置</span>
    _pos = newPos;
    <span style="color: rgb(0, 128, 0);">//球的速度衰减</span>
    _vel *= RuleSettings.Instance.BallDelayRate;

    <span style="color: rgb(0, 0, 255);">if</span> (!FieldSettings.Instance.LeftPNZ.IsInside(_pos))
    {
        CatchCommand.CanLeftTeamCatch = <span style="color: rgb(0, 0, 255);">true</span>;
    }
    <span style="color: rgb(0, 0, 255);">else</span> <span style="color: rgb(0, 0, 255);">if</span> (!FieldSettings.Instance.RightField.IsInside(_pos))
    {
        CatchCommand.CanRightTeamCatch = <span style="color: rgb(0, 0, 255);">true</span>;
    }
}</pre></div>
<p>&nbsp;</p>
<p>最后，我们可以看看这些命令究竟是如何影响球员和足球的：</p>
<p><a href="http://download.cnblogs.com/CnblogsSoccer/%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B/4%20%E7%90%83%E5%91%98%E5%9F%BA%E6%9C%AC%E5%91%BD%E4%BB%A4%E4%BB%A5%E5%8F%8A%E8%B6%B3%E7%90%83%E8%BF%90%E5%8A%A8%E8%A7%84%E5%88%99%E7%9A%84%E6%BC%94%E7%A4%BA.wmv" target="_blank">清晰版下载</a></p>
<p>&nbsp;<embed src="http://player.youku.com/player.php/sid/XNDAzODU2MjQ=/v.swf" type="application/x-shockwave-flash" quality="high" allowscriptaccess="sameDomain" width="480" align="middle" height="400"></p>
<p>在下一篇文章中，我们将讲解<a href="/gpcuster/archive/2008/08/27/1277335.html">整个比赛的执行流程</a>。</p>
<p>&nbsp;</p>
<p><a href="http://space.cnblogs.com/group/cnblogsSoccer">博客园仿真足球交流小组</a> 
</p><p><a href="http://space.cnblogs.com/group/topic/4424/">相关资源下载</a> 
</p><p><a href="/gpcuster/category/151459.html">相关文章</a></p><img src ="http://www.cnblogs.com/gpcuster/aggbug/1276409.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42129/" target="_blank">[新闻]GMail:回过头来支持IE6</a>]]></description></item><item><title>深入理解博客园仿真足球竞赛平台的仿真周期</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/25/1275483.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Mon, 25 Aug 2008 01:49:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/25/1275483.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1275483.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/25/1275483.html#Feedback</comments><slash:comments>11</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1275483.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1275483.html</trackback:ping><description><![CDATA[摘要: <img src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg" class="desc_img"/>
在上一篇文章中，我们讲解了如何使用如何利用CSharp球队模板编写自己的足球队，为了编写出更加智能的球队，我们需要进一步了解平台的仿真周期。&nbsp;&nbsp;<a href='http://www.cnblogs.com/gpcuster/archive/2008/08/25/1275483.html'>阅读全文</a><img src ="http://www.cnblogs.com/gpcuster/aggbug/1275483.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42128/" target="_blank">[新闻]Google十年大变样</a>]]></description></item><item><title>如何利用CSharp球队模板编写自己的足球队</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/22/1273768.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Fri, 22 Aug 2008 01:37:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/22/1273768.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1273768.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/22/1273768.html#Feedback</comments><slash:comments>14</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1273768.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1273768.html</trackback:ping><description><![CDATA[摘要: <img src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg" class="desc_img"/>
在上2篇文章中，我们介绍了博客园仿真足球竞赛平台的基本使用方法和它的基本工作原理。
在这篇文章中，我们将一起来了解如何使用c#球队的球队模板来编写自己的足球队。&nbsp;&nbsp;<a href='http://www.cnblogs.com/gpcuster/archive/2008/08/22/1273768.html'>阅读全文</a><img src ="http://www.cnblogs.com/gpcuster/aggbug/1273768.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42127/" target="_blank">[新闻]谷歌十年创新路</a>]]></description></item><item><title>博客园仿真足球竞赛平台基本原理分析</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272932.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Thu, 21 Aug 2008 03:13:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272932.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1272932.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272932.html#Feedback</comments><slash:comments>24</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1272932.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1272932.html</trackback:ping><description><![CDATA[<p>通过 <a href="http://download.cnblogs.com/CnblogsSoccer/%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B/1%20%E5%B9%B3%E5%8F%B0%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8.wmv">平台的基本使用.wmv</a>相信大家已经了解了整个平台的运行效果，下面我简单分析一下平台的基本运行原理，为大家编写属于自己的球队做好铺垫。</p>
<p><a href="/gpcuster/category/151459.html/rss">订阅本系列文章 <br></a></p><p><a href="/gpcuster/category/151459.html/rss"><br></a></p>
<p>简单地说，整个应用程序就是一个C/S的架构。在实习的运行中，包含1个Server（博客园仿真足球竞赛平台）和2个Client（大家编写的球队）。博客园仿真足球竞赛平台与大家编写的球队是通过TCP/IP来进行通信的。这也是为什么大家可以用任意自己擅长的语言来编写球队的核心原理。</p>
<p>启动博客园仿真足球竞赛平台的时候，他会以本机的IP地址作为自己的IP地址，然后将2个监听端口绑定到本机，用于监听将要上传的球队连接请求。然后我们启动球队，这个时候球队就会按照在配置文件中设置好的IP地址去连接我们的博客园仿真足球竞赛平台。当2个队伍都连接上以后，比赛就可以正式进行了。</p>
<p>当比赛开始运行的时候，平台会将整个比赛离散化，就好比咱们看动画片，都是由一帧一帧组成的。只不过咱们把这一帧叫做一个仿真周期，也就是一个周期。</p>
<p>仿真周期的执行过程如下：</p>
<p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/64b1eefd481a_13663/Drawing1_4.jpg"><img style="border: 0px none ;" alt="Drawing1" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/64b1eefd481a_13663/Drawing1_thumb_1.jpg" width="876" border="0" height="679"></a> </p>
<p>通过这个图片大家可以看到一个仿真周期可以划分为以下几个步骤：</p>
<blockquote>
<ol>
    <li>2个球队对分别从平台接收到本周期球场上的信息（比如我方的5个球员在什么位置，对方的5个球员在什么位置，足球的位置和速度）  </li>
    <li>球队根据得到的场上信息作出分析和判断（这就是我们要编写代码的部分），为本队的所有球员指定一个命令。  </li>
    <li>球队将每个球员的命令发送给服务器。  </li>
    <li>服务器接收到球员的命令以后，更新场上的信息（比如1号球员执行奔跑的命令，那么他的位置将会发生改变）。</li>
</ol>
</blockquote>
<p>&nbsp;</p>
<p>通过上面的分析可以看出，我们编写球队的工作就是，在得到了球场上的信息以后，如果对这些信息进行处理，并为每个队员计算出合适的命令。</p>
<p>大体流程也可以这样表示：</p>
<p><a href="/images/cnblogs_com/gpcuster/WindowsLiveWriter/64b1eefd481a_13663/Drawing2_2.jpg"><img style="border-width: 0px;" alt="Drawing2" src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/WindowsLiveWriter/64b1eefd481a_13663/Drawing2_thumb.jpg" width="350" border="0" height="272"></a> </p>
<p>&nbsp;</p>
<p>我们每个周期做的决策（为所有球队下达的命令）将逐步影响比赛的最终结果。所以说，计算好每一个周期的决策，将让我们赢得最后的比赛</p>
<p>&nbsp;</p>
<p>在下一篇文章中，我将与大家一起分享<a target="_blank" href="/gpcuster/archive/2008/08/22/1273768.html">如何使用c#球队的球队模板 来编写自己的足球队。</a></p>
<p>&nbsp;</p>
<p><a href="http://space.cnblogs.com/group/topic/4424/" target="_blank"></a></p>
<p><a href="http://space.cnblogs.com/group/cnblogsSoccer" target="_blank">博客园仿真足球交流小组</a> <br>
</p>
<p><a href="http://space.cnblogs.com/group/topic/4424/" target="_blank">相关资源下载</a></p>
<p><a href="/gpcuster/category/151459.html" target="_blank">相关文章</a></p>
<p><a href="http://space.cnblogs.com/group/cnblogsSoccer"></a></p><img src ="http://www.cnblogs.com/gpcuster/aggbug/1272932.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42126/" target="_blank">[新闻]十年回顾：Google的互联网经济</a>]]></description></item><item><title>释放你的编程技能与激情--博客园仿真足球竞赛平台预览</title><link>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272822.html</link><dc:creator>逖靖寒</dc:creator><author>逖靖寒</author><pubDate>Thu, 21 Aug 2008 02:16:00 GMT</pubDate><guid>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272822.html</guid><wfw:comment>http://www.cnblogs.com/gpcuster/comments/1272822.html</wfw:comment><comments>http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272822.html#Feedback</comments><slash:comments>43</slash:comments><wfw:commentRss>http://www.cnblogs.com/gpcuster/comments/commentRss/1272822.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/gpcuster/services/trackbacks/1272822.html</trackback:ping><description><![CDATA[摘要: <img src="http://www.cnblogs.com/images/cnblogs_com/gpcuster/footballlogo2.jpg" class="desc_img"/>在这个激情四射的夏季，在这个充满奇迹的2008.

让咱们全中国人骄傲的奥运会正在北京举行，在大家为中国加油，为奥运健儿加油的同时，博客园正在为大家准备一个以程序设计来展现自己编程水平的仿真机器人足球比赛平台:)&nbsp;&nbsp;<a href='http://www.cnblogs.com/gpcuster/archive/2008/08/21/1272822.html'>阅读全文</a><img src ="http://www.cnblogs.com/gpcuster/aggbug/1272822.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42126/" target="_blank">[新闻]十年回顾：Google的互联网经济</a>]]></description></item></channel></rss>