文档章节

拉登游戏开发--C#实现过程

secondriver
 secondriver
发布于 2015/09/17 09:24
字数 1755
阅读 13
收藏 0

     关于这个游戏的创意和较为深入的研究来自于新浪博客大力水手。

     拉登游戏的游戏思路是:

     一个N*N的方格,每个格子的有两种颜色状态(黑色,黄色);初始时所有格子为同一种颜色(比如:黑色),通过点击其中的一个格子,该格子以及其上下左右的格子的颜色将变为相反的颜色(之前黑色,之后黄色;反之亦然)。

    如下面六张图可以看到整个游戏的玩法

 初始状态 初始状态 初始状态 初始状态

点击 点击

   游戏开发过程考虑的几个问题:

  1.生成的N*N格子的应该自适应Window

  2.点击格子四周的格子的边界问题处理

  3.格子的颜色变化设置

  4.判断所有格子颜色是否发生改变

  5.如何实现自动完成功能

   游戏开发的关键就在于这个自动完成的算法实现。

   算法:

      格子共有N*N个,共N行N列,自动完成基于第一行的实现,每一个格子的状态只有两种,设为0或1.

   1.第0行有N个格子,每个格子共有2中状态,全排列共有Pow(2, N)中情况。

   2.给每一种情况进行编号[0,Pow(2,N))

    如下图3*3的格子,第0行的格子的状态:

      分析:第0行的状态共有Pow(2,N)中,接下来对第1行至第N-1一行进行遍历,每一行有N个格子进行点击处理,这样时间复杂度上升为:Pow(2, N)*Pow(N, 2)。如果N为32的时候,就仅仅让计算机走完这个数,Java中Integer.MAX_VALUE尝试了一下没有等到这个数就给Stop了。

      具大力水手的说法,目前通过分布式计算,已经完成到了N=35。每一种贴下来的图都是一幅美丽的图片(这个得仔细想象加观察)

     下面贴一张图:

   下面是C#版的部分代码程序较为简单,主要立足解决分布式问题。


  
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8. using System.Threading;  
  9.  
  10. namespace OkLight  
  11. {  
  12.     public partial class FormMain : Form  
  13.     {  
  14.         Button[] btns = new Button[25];  
  15.         //设置两个全局的数组变量  
  16.         static int[] states;  
  17.         static int[] operaters;  
  18.         //设置一个全局变量用来计算点击的次数  
  19.         static int count = 0;  
  20.  
  21.         //构造方法初始化组件  
  22.         public FormMain()  
  23.         {  
  24.             InitializeComponent();  
  25.         }  
  26.  
  27.         //初始化下拉菜单的选项值  
  28.         private void FormMainLoad(object sender, EventArgs e)  
  29.         {    
  30.               
  31.             int min = panelMain.Height;  
  32.             if (min > panelMain.Width)  
  33.             {  
  34.                 min = panelMain.Width;  
  35.             }  
  36.             int maxNumber = min / 40;  
  37.             for (int i = 1; i < maxNumber + 1; i++)  
  38.             {  
  39.                 comboBoxIndex.Items.Add(i);  
  40.             }  
  41.             comboBoxIndex.SelectedIndex = 4;  
  42.             InitalButton((int)comboBoxIndex.SelectedItem);  
  43.         }  
  44.  
  45.         //初始按钮  
  46.         private void InitalButton(int number)  
  47.         {  
  48.             panelMain.Controls.Clear();  
  49.              //获得面板的大小  
  50.             int x = (panelMain.Width - number*40) / 2;  
  51.             int y = (panelMain.Height - number * 40) / 2;  
  52.             btns = new Button[number * number];  
  53.  
  54.             //实例化按钮并且添加到面板中去  
  55.             for (int i = 0; i < number*number; i++)  
  56.             {  
  57.                 btns[i] = new Button();  
  58.                 btns[i].Width = 40;  
  59.                 btns[i].Height = 40;  
  60.                 //设置按钮的位置  
  61.                 btns[i].Left = x + (i % number) * 40;  
  62.                 btns[i].Top = y + (i / number) * 40;  
  63.                 //设置按钮表面的颜色  
  64.                 btns[i].BackColor = Color.Black;  
  65.                 //为每一个按钮注册单击处理  
  66.                 btns[i].Click += new EventHandler(FormMainClick);  
  67.                 panelMain.Controls.Add(btns[i]);  
  68.             }  
  69.  
  70.         }  
  71.  
  72.         //格子事件方法  
  73.         void FormMainClick(object sender, EventArgs e)  
  74.         {  
  75.             int number = (int)comboBoxIndex.SelectedItem;  
  76.             Button btn = sender as Button;  
  77.             //获得面板的大小  
  78.             int x = (panelMain.Width - 40*number) / 2;  
  79.             int y = (panelMain.Height - 40*number) / 2;  
  80.             //得到按钮的索引  
  81.             int i = (btn.Left - x) / 40;  
  82.             int j = (btn.Top - y) / 40;  
  83.             //得到当前单击的按钮的上下左右按钮的坐标  
  84.             int top = j - 1;  
  85.             int buttoom = j + 1;  
  86.             int left = i - 1;  
  87.             int right = i + 1;  
  88.             count++;  
  89.             ChangeButtonColor(btn);  
  90.             if (top >= 0)  
  91.             {  
  92.                 int index = i + number * top;  
  93.                 ChangeButtonColor(btns[index]);  
  94.             }  
  95.             if (buttoom < number)  
  96.             {  
  97.                 int index = i + number * buttoom;  
  98.                 ChangeButtonColor(btns[index]);  
  99.             }  
  100.             if(left>=0)  
  101.             {  
  102.                 int index = left + number * j;  
  103.                 ChangeButtonColor(btns[index]);  
  104.             }  
  105.             if (right < number)  
  106.             {  
  107.                 int index = right + number * j;  
  108.                 ChangeButtonColor(btns[index]);  
  109.             }  
  110.             showLabel.Text = "您当前已经点击次数为: " + count;  
  111.             if (IsSucceed(number))  
  112.             {  
  113.                DialogResult dr=MessageBox.Show("恭喜你,成功完成""消息");  
  114.             }  
  115.         }  
  116.  
  117.         //改变格子背景颜色  
  118.         private void ChangeButtonColor(Button btn)  
  119.         {  
  120.             if (btn.BackColor == Color.Black)  
  121.             {  
  122.                 btn.BackColor = Color.Yellow;  
  123.             }  
  124.             else 
  125.             {  
  126.                 btn.BackColor = Color.Black;  
  127.             }  
  128.             btn.Refresh();  
  129.  
  130.         }  
  131.  
  132.         //演示游戏  
  133.         private void GetShow(int number)  
  134.         {  
  135.             //设置方格的边的个数  
  136.             //计算格子的总个数  
  137.             int count = (int)Math.Pow(number, 2);  
  138.             //初始化数组的值  
  139.             //计算一共有多少种情况,number=5是32种情况  
  140.             //operaters数组中放的是每一种情况的每一个格子的操作取值  
  141.             //states数组中放的是每一种情况的每一个格子的状态取值  
  142.             //在计算过程中不一定将for语句运行完,当判断states[]的值全为1便可以终止  
  143.             for (int i = 0; i < (int)Math.Pow(2, number); i++)  
  144.             {  
  145.                 states = new int[count];  
  146.                 operaters = new int[count];  
  147.                 int x = i;//i表示第几种情况  
  148.                 int j = 0;  
  149.                 //进行第i种情况的operaters的赋值  
  150.                 while (true)  
  151.                 {  
  152.                     if (x == 0)  
  153.                     {  
  154.                         break;  
  155.                         //当x=0的时候跳出while循环  
  156.                     }  
  157.                     //将x转换为二进制数0 1  
  158.                     operaters[j] = x % 2;  
  159.                     x = x / 2;  
  160.                     j++;  
  161.                 }  
  162.                 //第i种情况的operaters[]设置完成之后进行操作  
  163.                 //这个操作只进行一行  
  164.                 for (int k = 0; k < number; k++)  
  165.                 {  
  166.                     //operaters[]值为1的时候表示操作  
  167.                     if (operaters[k] == 1)  
  168.                     {  
  169.                         ToClick(k, number);  
  170.                     }  
  171.                 }  
  172.  
  173.                 //对第i种情况下从第2行开始操作直到number行  
  174.                 for (int k = 1; k < number; k++)  
  175.                 {  
  176.                     //对第i种情况下从第k行的每一格格子开始操作  
  177.                     for (int m = 0; m < number; m++)  
  178.                     {  
  179.                         //判断k-1行第m格格子的状态  
  180.                         //在进行操作的时候,只点击上一行状态没有改变的格子对应下面的格子  
  181.                         //Console.Write(states[(k - 1) * number + m]);  
  182.                         if (states[(k - 1) * number + m] == 0)  
  183.                         {  
  184.                             //一旦将格子点击之后,它的操作状态就职位 1;  
  185.                             operaters[k * number + m] = 1;  
  186.                             ToClick(k * number + m, number);  
  187.                         }  
  188.  
  189.                     }  
  190.                 }  
  191.                 //通过计算可以判断是否已经完成操作  
  192.                 int statesCount = 0;  
  193.                 for (int k = 0; k < states.Length; k++)  
  194.                 {  
  195.                     if (states[k] == 1)  
  196.                     {  
  197.                         statesCount++;  
  198.                     }  
  199.                 }  
  200.                 //states[]的值和为count表明完成操作  
  201.                 if (statesCount == count)  
  202.                 {  
  203.                     break;  
  204.                 }  
  205.  
  206.             }  
  207.  
  208.         }  
  209.  
  210.         //判断游戏是否结束  
  211.         private bool IsSucceed(int number)  
  212.         {  
  213.             bool result = false;  
  214.             for (int i = 0, j = number * number; i < j; i++)  
  215.             {  
  216.                 if (btns[i].BackColor == Color.Black)  
  217.                 {  
  218.                     result = false;  
  219.                     break;  
  220.                 }  
  221.                 else 
  222.                 {  
  223.                     result = true;  
  224.                 }  
  225.             }  
  226.             return result;  
  227.         }  
  228.  
  229.         //下拉菜单改变信息  
  230.         private void SelectedIndexChanged(object sender, EventArgs e)  
  231.         {  
  232.             int number = (int)comboBoxIndex.SelectedItem;  
  233.             count = 0;  
  234.             showLabel.Text = "您当前已经点击次数为:";  
  235.             InitalButton(number);  
  236.         }  
  237.  
  238.         //点击格子事件  
  239.         private static void ToClick(int tag, int number)  
  240.         {  
  241.             //tag表示从操作中传递的值,它是格子从  [0-number*number)  的编号  
  242.             //计算行号  
  243.             int j = tag / number;  
  244.             //计算列号  
  245.             int i = tag % number;  
  246.             int left = i - 1;  
  247.             int right = i + 1;  
  248.             int top = j - 1;  
  249.             int buttom = j + 1;  
  250.             ChangeButtonStates(tag);  
  251.             if (left >= 0)  
  252.             {  
  253.                 ChangeButtonStates(left + number * j);  
  254.             }  
  255.             if (right < number)  
  256.             {  
  257.                 ChangeButtonStates(right + number * j);  
  258.             }  
  259.             if (top >= 0)  
  260.             {  
  261.                 ChangeButtonStates(i + number * top);  
  262.             }  
  263.             if (buttom < number)  
  264.             {  
  265.                 ChangeButtonStates(i + number * buttom);  
  266.             }  
  267.         }  
  268.  
  269.         //设置格子状态  
  270.         private static void ChangeButtonStates(int index)  
  271.         {  
  272.             if (states[index] == 0)  
  273.             {  
  274.                 states[index] = 1;  
  275.             }  
  276.             else 
  277.             {  
  278.                 states[index] = 0;  
  279.             }  
  280.         }  
  281.  
  282.         //游戏演示按钮事件  
  283.         private void BtnShowClick(object sender, EventArgs e)  
  284.         {  
  285.             int number = (int)comboBoxIndex.SelectedItem;  
  286.             GetShow(number);  
  287.             for(int i = 0; i < operaters.Length;i++)  
  288.             {  
  289.                if(operaters[i]==1)  
  290.                {  
  291.                    btns[i].PerformClick();  
  292.                    Thread.Sleep(1000);  
  293.                }  
  294.             }  
  295.         }  
  296.     }  
  297.       

      游戏算是成功的开发完了,而且这个游戏是没有终结点的。因为任何人在每一步都走对的情况下都没法通过鼠标点击走到N=32的情况去,甚至更小。这算是一个探讨分布式计算的一个非常好的实例。

本文出自 “野马红尘” 博客,谢绝转载!

© 著作权归作者所有

共有 人打赏支持
secondriver
粉丝 10
博文 229
码字总数 233821
作品 0
广州
程序员
私信 提问
游戏AI的开发框架组件--Behaviac

Behaviac是游戏AI的开发框架组件,也是游戏原型的快速设计工具。支持行为树BT,状态机FSM,HTN等多种范式,方便的编辑和调试。支持全平台,适用于客户端和服务器,助力游戏快速迭代开发。 编...

匿名
2016/03/29
14.9K
5
使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍

一、前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台。用于帮助中小型软件企业建立一条适合市场快速变化的...

agilelab
2014/01/09
0
0
ScutSDK 0.95 版本发布

ScutSDK 简介: ScutSDK 是和 Scut 游戏服务器引擎,简化客户端开发的配套 SDK,她彻底打通了 Scut 开源游戏服务器引擎与客户端引擎(如Cocos2d-x/Quick-x/Unity3D)项目间的通信,进而实现整...

ScutGame
2013/12/24
1K
0
对于质疑.Net语言的那些人,我只能告诉你们,你们不懂.... ...

最近这些年我一直用c#开发,因为C#和.Net的非常棒的软件开发语言和平台,我感觉C#正是我想要的语言,用它既能开发上层东西,也能开发底层代码,更重要的是,用它开发unity3d游戏,已是将来的...

八一戒
2013/06/08
25.7K
56
C#游戏开发快速入门教程Unity5.5教程

C#游戏开发快速入门教程Unity5.5教程 试读文档下载地址:http://pan.baidu.com/s/1slwBHoD C#是微软发布的高级程序设计语言,这门语言和C语言一样,已经成为了大学计算机相关专业必学的一门语...

大学霸
2014/09/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

单点登录实现原理(SSO)

简介 单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源,像一些...

echojson
32分钟前
0
0
介绍Python中6个序列的内置类型

1、Python中6个序列的内置类型分别是什么? Python包含6中内建的序列,即列表、元组、字符串、Unicode字符串、buffer对象和 xrange 对象。序列通用的操作包括:索引、长度、组合(序列相加)...

问题终结者
53分钟前
3
0
用python自制微信机器人,定时发送天气预报

0 引言 前段时间找到了一个免费的天气预报API,费了好段时间把这个API解析并组装成自己想用的格式了,就想着如何实现每天发送天气信息给自己。最近无意中发现了wxpy库,用它来做再合适不过了...

上海小胖
今天
8
0
深入理解java虚拟机-垃圾收集器与内存分配策略

垃圾收集器与内存分配策略 引用计数法 就是给对象添加一个计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1,计数器为0的对象就是不可能再被使用的。 缺点:无法...

须臾之余
今天
8
0
Python+Appium自动化测试环境搭建

1.Android SDK 下载SDK并配置系统环境变量ANDROID_HOME。 2.Appium 2.1 直接下载安装 官网下载安装appium-desktop-setup.exe。 2.2 通过npm下载安装 appium本质是一个nodejs库所以要先安装n...

维他ViTa
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部