精华内容
下载资源
问答
  • 井字游戏 井字游戏
  • 井字游戏(ReactJS App) 一个简单的井字游戏,让您熟悉React。 我遵循了本教程: : 熟悉了React,这导致了常规的井字游戏。 然后,我继续使用该教程的知识来创建Ultimate Tic-Tac-Toe版本。 我CSS和HTML功能...
  • 井字游戏 基于终端的井字游戏,允许单人或两人游戏 将main.cpp文件下载到所需的目标位置 使您将main.cpp存储在当前目录中的任何文件夹 在终端运行 g ++ -std = c ++ 14 main.cpp -o tictactoe 其次是 ./tictactoe
  • 该项目是通过。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行应用程序。 打开在浏览器中查看。 如果进行编辑,页面将重新加载。 您还将在控制台中看到任何棉绒错误。... 在交互式监视模式下启动...
  • 井字游戏 一个有趣的井字游戏(XO),可与您的朋友一起玩,是用c ++制作的。 用法 您可以在找到并下载执行的(.exe)代码。 预览
  • 井字游戏 井字游戏复制代码/下载文件,运行并享受游戏
  • Create React App入门 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: npm start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何...
  • 井字游戏-源码

    2021-02-23 10:57:28
    井字游戏 面向对象的Javascrript的实践项目 项目启动:02-21-2021 索非亚·阿科斯塔(Sofia Acosta)和猫登顿(Cat Denton) 项目描述 Tic Tac Toe是两个玩家的游戏。 眼镜 Describe: Test: "It should return an ...
  • python编写井字棋 Programming computer games may be the most technically challenging (and possibly the best paying) job that a programmer can have. Top level games require the best from both ...

    python编写井字棋

    Programming computer games may be the most technically challenging (and possibly the best paying) job that a programmer can have. Top level games require the best from both programmers and computers.

    计算机游戏进行编程可能是程序员可以从事的技术上最具挑战性的工作(可能是报酬最高的工作)。 顶级游戏需要程序员和计算机的鼎力支持。

    Visual Basic 6 has now been thoroughly bypassed as a platform for game programming. (It never really was one. Even in the "good ol' days", serious game programmers would never use a high-level language like VB 6 because you just couldn't get the cutting edge performance that most games require.) But the simple "Tic Tac Toe" game is a great introduction to programming that is a little more advanced than "Hello World!"

    现在, Visual Basic 6已被完全绕开作为游戏编程平台。 (它从来不是真正的一个。即使在“好日子”中,严肃的游戏程序员也永远不会使用VB 6这样的高级语言,因为您无法获得大多数游戏所要求的最先进的性能。)但是简单的“井字游戏”是对编程的一个很好的介绍,它比“ Hello World!”要先进一些

    This is a great introduction to many of the fundamental concepts of programming since it combines techniques including:

    这是对许多编程基本概念的精彩介绍,因为它结合了以下技术:

    • The use of arrays. The X and O markers are kept in separate arrays and the entire arrays are passed between functions to keep track of the progress of the game.

      使用数组 。 X和O标记保存在单独的数组中,整个数组在函数之间传递,以跟踪游戏的进度。

    • Using VB 6 level graphics: VB 6 doesn't offer great graphical capability, but the game is a good introduction to what is available. Much of the rest of this series is an exploration of how GDI+, the next generation of Microsoft graphics, replaces the VB 6 level graphics.

      使用VB 6级别的图形:VB 6没有提供强大的图形功能,但是该游戏很好地介绍了可用的功能。 本系列其余大部分内容探讨了下一代Microsoft图形GDI +如何替代VB 6级图形。
    • Using math calculations for program control: The program uses clever modulo (Mod) and integer division calculations using the two-game marker arrays to determine when a three-element "win" has occurred.

      使用数学计算进行程序控制:程序使用巧妙的模数(Mod)和整数除法计算,并使用两个游戏标记数组确定何时发生了三元素“胜利”。

    The class of programming in this article is perhaps just a little past the beginning level but it should be good for "intermediate" programmers. But let's start at an elementary level to illustrate some of the concepts and get you started with your Visual Basic game programming career. Even students more advanced than that may find that it's slightly challenging to get the objects in the form just right.

    本文中的编程类别可能仅比入门水平稍高一点,但是对“中级”程序员来说应该是不错的选择。 但是,让我们从基本的层次开始说明一些概念,并开始您的Visual Basic游戏编程生涯。 即使是比这更高级的学生,也可能会发现,正确放置表单中的对象有些挑战。

    如何玩井字游戏 ( How to Play Tic Tac Toe )

    If you've never played Tic Tac Toe, here are the rules. Two players alternate at placing Xs and Os into 3 x 3 playing field.

    如果您从未玩过Tic Tac Toe ,请遵循以下规则。 两名玩家交替将X和O放置在3 x 3的游戏场地中。

    Before the game starts, both players have to agree about who will go first and who will mark his moves with which symbol. After the first move, the players alternately place their marks in any empty cell. The goal of the game is to be the first player with three marks in a horizontal, diagonal or vertical line. If there are no empty cells and neither player has a winning combination, the game is a draw.

    在游戏开始之前,两个玩家都必须就谁先走以及谁将用哪个符号标记自己的动作达成一致。 第一步之后,玩家将标记交替放置在任何空白单元格中。 游戏的目标是成为第一个在水平,对角线或垂直线上带有三个标记的玩家。 如果没有空单元,并且没有玩家有获胜组合,则该游戏为平局。

    启动程序 ( Starting the Program )

    Before starting any actual coding, it's always a good idea to change the names of any components you use. Once you start coding, the name will be used automatically by Visual Basic so you want it to be the right name. We'll use the form name frmTicTacToe and we'll also change the caption to "About Tic Tac Toe."

    在开始任何实际编码之前,最好更改您使用的任何组件的名称。 一旦开始编码 ,Visual Basic将自动使用该名称,因此您希望它是正确的名称。 我们将使用表单名称frmTicTacToe ,并将标题更改为“关于井字游戏”。

    With the form established, use the line toolbox control to draw a 3 x 3 grid. Click the line tool, then draw a line where you want it. You'll have to create four lines this way and adjust their length and position to make them look right. Visual Basic also has some convenient tools under the Format menu that will help. This is a great chance to practice with them.

    建立表单后,使用线条工具箱控件绘制一个3 x 3的网格。 单击线条工具,然后在所需位置画一条线。 您必须以这种方式创建四行,并调整其长度和位置以使其看起来正确。 Visual Basic在“格式”菜单下还提供了一些方便的工具,这些工具会有所帮助。 这是和他们一起练习的绝好机会。

    In addition to the playing grid, we'll need some objects for the X and O symbols that will be placed on the grid. Since there are nine spaces in the grid, we'll create an object array with nine spaces, called elements in Visual Basic.

    除了播放网格外,我们还需要一些将用于放置在网格上的X和O符号的对象。 由于网格中有9个空格,因此我们将创建一个具有9个空格的对象数组,在Visual Basic中称为元素。

    There are several ways to do just about everything in the Visual Basic development environment, and creating control arrays is is no exception. Probably the easiest way is to create the first label (click and draw just like the line tool), name it, set all of the attributes (such as Font and ForeColor), and then make copies of it. VB 6 will ask if you want to create a control array. Use the name lblPlayGround for the first label.

    在Visual Basic开发环境中,有几种方法可以完成所有事情,创建控件数组也不例外。 可能最简单的方法是创建第一个标签(单击并绘制,就像线条工具一样),命名它,设置所有属性(例如Font和ForeColor),然后复制它。 VB 6将询问您是否要创建控件数组。 将名称lblPlayGround用作第一个标签。

    To create the other eight elements of the grid, select the first label object, set the Index property to zero, and press CTRL+C (copy). Now you can press CTRL+V (paste) to create another label object. When you copy objects like this, each copy will inherit all properties except Index from the first one. Index will increase by one for each copy. This is a control array because they all have the same name, but different index values.

    若要创建网格的其他八个元素,请选择第一个标签对象,将Index属性设置为零,然后按CTRL + C(复制)。 现在,您可以按CTRL + V(粘贴)来创建另一个标签对象。 当您像这样复制对象时,每个副本都将继承除第一个索引以外的所有属性。 每个副本的索引将增加一。 这是一个控制数组,因为它们都具有相同的名称,但索引值不同。

    If you create the array this way, all of the copies will be stacked on top of each other in the upper left corner of the form. Drag each label to one of the playing grid positions. Be sure that index values are sequential in the grid. The logic of the program depends on it. The label object with index value 0 should be in the top left corner, and the bottom right label should have index 8. If the labels cover the playing grid, select each label, right-click, and select Send to Back.

    如果以这种方式创建阵列,则所有副本将在窗体的左上角彼此堆叠。 将每个标签拖到播放网格位置之一。 确保索引值在网格中是连续的。 程序的逻辑取决于它。 索引值为0的标签对象应位于左上角,而右下方的标签应具有索引8。如果标签覆盖了播放网格,请选择每个标签,单击鼠标右键,然后选择“发送回”。

    Since there are eight possible ways to win the game, we'll need eight different lines to show the win on the playing grid. You will use the same technique to create another control array. First, draw the line, name it linWin, and set the Index property to zero. Then use copy-paste technique to produce seven more lines. The following illustration shows how to set the index numbers correctly.

    由于有八种可能的方式来赢得比赛,因此我们需要八条不同的线来显示比赛中的胜利。 您将使用相同的技术来创建另一个控件数组。 首先,绘制线条,将其命名为linWin,并将Index属性设置为零。 然后使用复制粘贴技术再产生七行。 下图显示了如何正确设置索引号。

    In addition to the label and line objects, you need some command buttons to play the game and more labels to keep score. The steps to create these are not detailed here, but these are the objects you need.

    除了标签和线条对象之外,您还需要一些命令按钮来玩游戏,还需要更多标签来保持得分。 创建这些步骤的步骤不在此处详述,但是这些是您需要的对象。

    Two button objects:

    两个按钮对象

    • cmdNewGame

      cmdNewGame
    • cmdResetScore

      cmdResetScore

    Frame object fraPlayFirst containing two option buttons:

    框架对象fraPlayFirst包含两个选项按钮:

    • optXPlayer

      optXPlayer
    • optOPlayer

      optOPlayer

    Frame object fraScoreBoard containing six labels. Only lblXScore and lblOScore are changed in the program code.

    框架对象fraScoreBoard包含六个标签。 程序代码中仅lblXScore和lblOScore被更改。

    • lblX

      bl
    • lblXScore

      lblXScore
    • lblO

      bl
    • lblOScore

      lblOScore
    • lblMinus

      lblMinus
    • lblColon

      lbl冒号

    Finally, you also need the label object lblStartMsg to 'mask' the cmdNewGame button when it shouldn't be clicked. This isn't visible in the illustration below because it occupies the same space in the form as the command button. You may have to move the command button temporarily to draw this label on the form.

    最后,当不应该单击cmdNewGame按钮时,还需要标签对象lblStartMsg对其进行“遮罩”。 这在下图中不可见,因为它在窗体中与命令按钮占据相同的空间。 您可能必须暂时移动命令按钮才能在表单上绘制此标签。

    So far, no VB coding has been done, but we're finally ready to do that.

    到目前为止,还没有完成VB编码,但是我们终于准备好了。

    初始化 ( Initialization )

    Now you get to finally start coding the program. If you haven't already, you might want to download the source code to follow along as the operation of the program is explained.

    现在,您终于可以开始对程序进行编码了。 如果尚未下载源代码,则可能需要下载源代码以跟随程序的操作说明。

    One of the first design decisions to make is how to keep track of the current 'state' of the game. In other words, what are the current Xs and Os on the playing grid and who moves next. The concept of 'state' is critical in a lot of programming, and in particular, it's important in programming ASP and ASP.NET for the web

    首先要做出的设计决定之一就是如何跟踪游戏的当前“状态”。 换句话说,当前在游戏网格上的X和O是什么,接下来是谁。 “状态”的概念在许多编程中都至关重要,尤其是在为Web编程ASP和ASP.NET时很重要

    There are several ways that this could be done, so it's a critical step in the analysis. If you were solving this problem on your own, you might want to draw a flowchart and try out different options with 'scratch paper' before starting any coding.

    有几种方法可以完成此操作,因此这是分析中的关键步骤。 如果您自己解决此问题,则可能需要绘制流程图并尝试使用“草稿纸”尝试其他选项,然后再开始编码。

    变数 ( Variables )

    Our solution uses two "two-dimensional arrays" because that helps keep track of 'state' by simply changing the array indexes in program loops. The state of the top-left corner will be in the array element with index (1, 1), the top-right corner will be in (1, 3), the bottom-right in (3,3), and so forth. The two arrays that do this are:

    我们的解决方案使用两个“二维数组”,因为这可以通过简单地在程序循环中更改数组索引来帮助跟踪“状态”。 左上角的状态将在索引为(1,1)的数组元素中,右上角将在(1,3)中,右下角在(3,3)中,依此类推。 执行此操作的两个数组是:

    iXPos(x, y)
    iXPos(x,y)

    and

    iOPos(x, y)
    iOPos(x,y)

    There are a lot of different ways this can be done and the final VB.NET solution in this series shows you how to do it with just a single one-dimensional array.

    有很多不同的方法可以完成此操作,本系列的最终VB.NET解决方案将向您展示如何仅使用一个一维数组来完成此操作。

    The programming to translate these arrays into player win decisions and visible displays in the form are on the next page.

    在下一页上将这些数组转换为玩家获胜决定和表格中可见显示的程序。

    You also need a few global variables as follows. Notice that these are in the General and Declarations code for the form. This makes them "module level" variables that can be referenced anywhere in the code for this form. For more on this, check Understanding the Scope of Variables in Visual Basic Help.

    您还需要一些全局变量,如下所示。 请注意,这些在表单的“常规”和“声明”代码中。 这使它们成为“模块级”变量,可以在此表单的代码中的任何地方引用。 有关此的更多信息,请在Visual Basic帮助中选中“了解变量的范围”。

    There are two areas where variables are initialized in our program. First, a few variables are initialized while the form frmTicTacToe is loading.

    在我们的程序中有两个初始化变量的区域。 首先,在加载frmTicTacToe表单时初始化一些变量。

    Private Sub Form_Load()
    私人子Form_Load()

    Second, before each new game, all variables that need to be reset to starting values are assigned in an initialization subroutine.

    其次,在每个新游戏之前,所有需要重置为初始值的变量都在初始化子例程中分配。

    Sub InitPlayGround()
    子InitPlayGround()

    Note that the form load initialization also calls the playground initialization.

    请注意,表单加载初始化也称为游乐场初始化。

    One of the critical skills of a programmer is the ability to use the debugging facilities to understand what the code is doing. You can use this program to try:

    程序员的一项关键技能是能够使用调试工具来了解代码在做什么。 您可以使用此程序尝试:

    • Stepping through the code with the F8 key

      使用F8键单步执行代码
    • Setting a watch on key variables, such as sPlaySign or iMove

      监视关键变量,例如sPlaySign或iMove

      Setting a breakpoint and querying the value of variables. For example, in the inner loop of the initialization:

      设置断点并查询变量的值。 例如,在初始化的内部循环中:

    lblPlayGround((i - 1) * 3 + j - 1).Caption = ""
    lblPlayGround((i-1)* 3 + j-1).Caption =“”

    Note that this program clearly shows why it's a good programming practice to keep data in arrays whenever possible. If you did not have arrays in this program, you would have to write code something like this:

    请注意,该程序清楚地说明了为什么尽可能将数据保留在数组中是一种好的编程习惯。 如果此程序中没有数组,则必须编写如下代码:


    Line1.Visible = False
    Line1.Visible = False
    Line2.Visible = False
    Line2.Visible = False
    Line3.Visible = False
    Line3.Visible = False
    Line4.Visible = False
    Line4.Visible = False
    Line5.Visible = False
    Line5.Visible = False
    Line6.Visible = False
    Line6.Visible = False
    Line7.Visible = False
    Line7.Visible = False

    instead of this:

    代替这个:


    linWin(i).Visible = False
    linWin(i).Visible = False
    Next i
    接下来我

    采取行动 ( Making a Move )

    If any part of the system can be thought of as 'the heart', it's subroutine lblPlayGround_Click. This subroutine is called every time a player clicks the playing grid. (Clicks must be inside one of the nine lblPlayGround elements.) Notice that this subroutine has an argument: (Index As Integer). Most of the other 'event subroutines', like cmdNewGame_Click() do not. Index indicates which label object has been clicked. For example, index would contain the value zero for the top-left corner of the grid and the value eight for the bottom-right corner.

    如果系统的任何部分都可以视为“心脏”,则它是子例程lblPlayGround_Click。 每当玩家单击播放网格时,都会调用此子例程。 (单击必须在9个lblPlayGround元素之一之内。)请注意,此子例程具有一个参数:(整数索引)。 其他大多数“事件子例程”(例如cmdNewGame_Click())都没有。 索引指示已单击的标签对象。 例如,索引将包含网格左上角的值零和右下角的值八。

    After a player clicks a square in the game grid, the command button to start another game, cmdNewGame, is "turned on' by making it visible. The state of this command button does double duty because it's also used as a boolean decision variable later in the program. Using a property value as a decision variable is usually discouraged because if it ever becomes necessary to change the program (say, for example, to make the cmdNewGame command button visible all the time), then the program will unexpectedly fail because you might not remember that it's also used as part of the program logic. For this reason, it's always a good idea to search through program code and check the use of anything you change when doing program maintenance, even property values. This program violates the rule partly to make this point and partly because this is a relatively simple piece of code where it's easier to see what is being done and avoid problems later.

    玩家单击游戏网格中的正方形后,通过使其可见而“打开”了用于启动另一个游戏cmdNewGame的命令按钮。此命令按钮的状态起着双重作用,因为稍后它也用作布尔决策变量通常不建议使用属性值作为决策变量,因为如果有必要更改程序(例如,使cmdNewGame命令按钮始终可见),则程序将意外失败,因为您可能不记得它也被用作程序逻辑的一部分,因此,搜索程序代码并检查在进行程序维护时更改的内容(甚至是属性值)的使用始终是一个好主意。规则部分是为了说明这一点,部分是因为这是一段相对简单的代码,在其中更容易看到正在执行的操作并避免以后出现问题。

    A player selection of a game square is processed by calling the GamePlay subroutine with Index as the argument.

    通过调用以Index为参数的GamePlay子例程来处理游戏方的玩家选择。

    处理移动 ( Processing the Move )

    First, you check to see if an unoccupied square was clicked.

    首先,您检查是否单击了未占用的正方形。

    If lblPlayGround(xo_Move).Caption = "" Then
    如果lblPlayGround(xo_Move).Caption =“”然后

    Once we're sure this is a legitimate move, the move counter (iMove) is incremented. The next two lines are very interesting since they translate the coordinates from the one-dimensional If lblPlayGround component array to two-dimensional indexes that you can use in either iXPos or iOPos. Mod and integer division (the 'backslash') are mathematical operations that you don't use every day, but here's a great example showing how they can be very useful.

    一旦确定这是合法的移动,移动计数器(iMove)就会增加。 接下来的两行非常有趣,因为它们将坐标从一维If lblPlayGround组件数组转换为可以在iXPos或iOPos中使用的二维索引。 Mod和整数除法(“反斜杠”)是您每天都不会使用的数学运算,但是,这是一个很好的示例,展示了它们如何非常有用。


    iMove = iMove + 1
    iMove = iMove +1
    x = Int(xo_Move / 3) + 1
    x =整数(xo_Move / 3)+ 1
    y = (xo_Move Mod 3) + 1
    y =(xo_Move Mod 3)+ 1

    The xo_Move value 0 will be translated to (1, 1), 1 to (1, 2) ... 3 to (2, 1) ... 8 to (3, 3).

    xo_Move值0将转换为(1,1),1转换为(1,2)... 3转换为(2,1)... 8转换为(3,3)。

    The value in sPlaySign, a variable with module scope, keeps track of which player made the move. Once the move arrays are updated, the label components in the playing grid can be updated with the appropriate sign.

    sPlaySign中的值(具有模块范围的变量)会跟踪哪个玩家进行了移动。 一旦更新了移动数组,就可以使用适当的符号来更新播放网格中的标签组件。


    iOPos(x, y) = 1
    iOPos(x,y)= 1
    iWin = CheckWin(iOPos())
    iWin = CheckWin(iOPos())
    Else
    其他
    iXPos(x, y) = 1
    iXPos(x,y)= 1
    iWin = CheckWin(iXPos())
    iWin = CheckWin(iXPos())
    End If
    万一
    lblPlayGround(xo_Move).Caption = sPlaySign
    lblPlayGround(xo_Move).Caption = sPlaySign

    For example, when the X player clicks the top left corner of the grid, variables will have the following values:

    例如,当X播放器单击网格的左上角时,变量将具有以下值:

    The user screen shows only an X in the upper left box, while the iXPos has a 1 in the upper left box and 0 in all of the others. The iOPos has 0 in every box.

    用户屏幕在左上方的框中仅显示一个X,而iXPos在左上方的框中显示为1,其他所有字段均为0。 iOPos在每个框中都有0。

    The values changes when the O player clicks the center square of the grid. Now th iOPos shows a 1 in the center box while the user screen shows an X in the upper left and an O in the center box. The iXPos shows only the 1 in the upper left corner, with 0 in all of the other boxes.

    当O播放器单击网格的中心正方形时,值会更改。 现在,iOPos在中心框中显示1,而用户屏幕在左上方显示X,在中心框中显示O。 iXPos在左上角仅显示1,在所有其他框中显示0。

    Now that you know where a player clicked, and which player did the clicking (using the value in sPlaySign), all you have to do is find out if someone won a game and figure out how to show that in the display.

    既然您知道了某个玩家单击的位置以及该玩家单击的位置(使用sPlaySign中的值),那么您所要做的就是找出某人是否赢得了一场比赛,并弄清楚如何在屏幕上显示出来。

    寻找赢家 ( Finding a Winner )

    After each move, the CheckWin function checks for the winning combination. CheckWin works by adding down each row, across each column and through each diagonal. Tracing the steps through CheckWin using Visual Basic's Debug feature can be very educational. Finding a win is a matter of first, checking whether three 1's were found in each of the individual checks in the variable iScore, and then returning a unique "signature" value in Checkwin that is used as the array index to change the Visible property of one element in the linWin component array. If there is no winner, CheckWin will contain the value -1. If there is a winner, the display is updated, the scoreboard is changed, a congratulation message is displayed, and the game is restarted.

    每次移动后,CheckWin函数都会检查获胜组合。 CheckWin的工作原理是将每一行,每一列和每个对角线相加。 使用Visual Basic的“调试”功能通过CheckWin跟踪步骤可能非常有教育意义。 首先要找到一个胜利,首先检查在变量iScore的每个检查中是否都找到三个1,然后在Checkwin中返回一个唯一的“签名”值,该值用作更改数组的Visible属性的数组索引。 linWin组件数组中的一个元素。 如果没有获胜者,CheckWin将包含值-1。 如果有赢家,则更新显示,更改记分牌,显示祝贺消息,然后重新开始比赛。

    Let's go through one of the checks in detail to see how it works. The others are similar.

    让我们详细检查其中一项以了解其工作原理。 其他类似。


    For i = 1 To 3
    对于i = 1至3
    iScore = 0
    iScore = 0
    CheckWin = CheckWin + 1
    CheckWin = CheckWin +1
    For j = 1 To 3
    对于j = 1到3
    iScore = iScore + iPos(i, j)
    iScore = iScore + iPos(i,j)
    Next j
    下一个j
    If iScore = 3 Then
    如果iScore = 3,则
    Exit Function
    退出功能
    End If
    万一
    Next i
    接下来我

    The first thing to notice is that the first index counter i counts down the rows while the second j counts across the columns. The outer loop, then simply moves from one row to the next. The inner loop counts the 1's in the current row. If there are three, then you have a winner.

    首先要注意的是,第一个索引计数器i对行进行递减计数,而第二个索引计数器i对列进行计数。 然后,外循环仅从一行移到下一行。 内部循环在当前行中计数1。 如果有三个,那么您就有赢家。

    Notice that you also keep track of the total number of squares tested in the variable CheckWin, which is the value passed back when this function terminates. Each winning combination will end up with a unique value in CheckWin from 0 to 7 which is used to select one of the elements in the linWin() component array. This makes the order of the code in function CheckWin important too! If you moved one of the blocks of loop code (like the one above), the wrong line would be drawn on the playing grid when someone wins. Try it and see!

    请注意,您还可以在CheckWin变量中跟踪测试的平方总数,该变量是此函数终止时传回的值。 每个获胜组合最终将在CheckWin中从0到7拥有一个唯一值,该唯一值用于选择linWin()组件数组中的元素之一。 这也使功能CheckWin中的代码顺序很重要! 如果您移动了循环代码块之一(如上面的代码块),则当有人获胜时,会在播放网格上画错线。 试试看!

    整理细节 ( Finishing Details )

    The only code not yet discussed is the subroutine for a new game and the subroutine that will reset the score. The rest of the logic in the system makes creating these quite easy. To start a new game, you have only to call the InitPlayGround subroutine. As a convenience for players since the button could be clicked in the middle of a game, you ask for confirmation before going ahead. You also ask for confirmation before restarting the scoreboard.

    尚未讨论的唯一代码是新游戏的子例程和将重置得分的子例程。 系统中的其余逻辑使创建这些逻辑变得非常容易。 要开始新游戏,您只需调用InitPlayGround子例程。 为了方便玩家,因为可以在游戏过程中单击按钮,因此在进行下一步操作之前,您需要先进行确认。 您还需要在重新启动记分板之前进行确认。

    翻译自: https://www.thoughtco.com/programming-the-tic-tac-toe-game-4079040

    python编写井字棋

    展开全文
  • 使用git下载样板 $ git clone https://github.com/4GeeksAcademy/react-hello.git $ cd react-hello 并安装npm软件包: $ npm install 开始编码! 对于Windows,Mac,Linux或Gitpod,请通过实时重新启动来启动...
  • 资源介绍:易语言井字游戏源码资源作者:易语言如何写游戏资源界面:资源下载
  • c#人机对战井字游戏源代码,可了解下棋盘的绘制、 电脑下棋的逻辑,判断输赢,修改所下棋子的颜色,修改该标签上的Owner的值为当前玩家;用到了C#自定义控件GameClass.dll,也包括有源码,生成GameClass.dll要拷贝到...
  • 井字游戏 C++实现

    2010-02-20 11:17:52
    一个适合初学者看看的小游戏程序,欢迎下载
  • 井字游戏 Carter Kerstetter创建的一款适用于Android手机的井字游戏。 该游戏具有容易,中等和困难的AI可供对抗。 要在Android手机上运行游戏,请执行以下操作: 下载位于TicTacToe / app / release中的app-...
  • 颤振多平台井字游戏 井字游戏的多平台Flutter示例游戏。 谈话 我最近进行了演讲,在实时编码演示中构建了该应用程序,以展示Flutter,然后做了一些黑客操作,使其可在移动设备,台式机和Web上正常工作。 如果您对...
  • 井字棋小游戏

    2013-08-24 21:04:08
    附源代码,供c++初学者学习。建议下载dev-c。
  • WPF-MVVM井字游戏源码 源码描述: WPF-MVVM井字游戏源码 该源码演示了如何实现MVVM模式在一个WPF应用程序中 View:UI界面 ViewModel:它是View的抽象,负责View与Model之间信息转换,将View的Command传送到...
  • 井字游戏 这是一个TicTacToeAI,它实现了Minimax算法以最大化其潜在结果并最小化玩家的结果。 安装 下载并解压缩zip,然后运行game.py。 python3 game.py 用法 Board layout : 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |...
  • 井字游戏或变形游戏 Tic-Tac-Toe是一款有趣的游戏,连续赢得3个即可获胜。 但是,该项目的主要部分是展示git-hub上的案例团队合作。 团队合作和沟通是任何项目中最伟大的创造者/破坏者之一。 使用以下方法开始小型...
  • 井字游戏 一个简单的井字游戏,用 gui 制作。 您可以在下载 jar 文件中项目的最新版本。
  • Java Swing井字游戏

    2020-05-03 23:05:39
    大家好! 哇,自从我在这里发布了东西以来已经有一段时间了... 它是一个TicTacToe游戏应用程序。 从这个特定的程序中学到的东西不多,但是我真的想摆脱这种僵局,因此我今天就发布这个。 我实际上写了这段代码是为了...
    大家好! 哇,自从我在这里发布了东西以来已经有一段时间了! 我必须说我真的很想写东西,而且我保证我不会再陷入“作家的障碍”。 希望 :) ..最近两个月发生了很多事情,我有很多话要说。 但是在这篇文章中,我只是要发布我之前写的一个小应用程序。 它是一个TicTacToe游戏应用程序。 从这个特定的程序中学到的东西不多,但是我真的想摆脱这种僵局,因此我今天就发布这个。

    我实际上写了这段代码是为了向我的一位朋友展示Java的一些非常酷的功能,这些朋友也以“ C ++”风格编写了相同的应用程序。 而且我的那个朋友甚至为计算机播放器开发了代码。 但是在完成他的代码后,他可悲地意识到了一个基本事实,即如果你玩的很好,你将无法在井字游戏中获胜! 呵呵 :D 所以我没有冒险进入那个领域。 老实说,我对编写AI应用程序并不感兴趣。 但由于我喜欢网络编程,因此我想到了向该应用程序添加网络多人游戏功能。 但是很遗憾,我还没有时间这样做。
    Anywaiz应用程序的工作方式如下-游戏启动后即自动启动,状态栏指示现在轮到哪个玩家,剩下的只是简单的玩法! 在游戏结束时,该应用程序将自动重置。 进入代码。

    import javax.swing.*;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.util.logging.Logger;
    
    /**
    * TicTacToe Application
    * @author Steve Robinson
    * @version 1.0
    */
    
    class TicTacToeFrame extends JFrame
    {
    
     JButton [][] buttons= new JButton[3][3];
     JTextField statusBar;
     GamePanel panel;
     Integer turn;
     GameListener listener=new GameListener();
     Integer count;
    
     public TicTacToeFrame()
     {
      setLayout(new BorderLayout());
    
      panel=new GamePanel();
      add(panel,BorderLayout.CENTER);
    
      statusBar=new JTextField("Player1's Turn");
      statusBar.setEditable(false);
      add(statusBar,BorderLayout.SOUTH);
    
      setTitle("Tic Tac Toe!");
      setVisible(true);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setBounds(400,400,300,300);
     }
    
     class GamePanel extends JPanel
     {
    
      public GamePanel()
      {
       setLayout(new GridLayout(3,3));
       turn =1;
       count=0;
       for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)   {
         buttons[i][j]=new JButton();
         buttons[i][j].putClientProperty("INDEX", new Integer[]{i,j});
         buttons[i][j].putClientProperty("OWNER", null);
         buttons[i][j].addActionListener(listener);
         add(buttons[i][j]);
        }
      }
     }
    
     class GameListener implements ActionListener
     {
      public void actionPerformed(ActionEvent e)
      {
       count++;
       JButton b=(JButton)e.getSource();
       Integer[]index=(Integer[]) b.getClientProperty("INDEX");
    
       //System.out.println(turn); //turn                  //   //System.out.println("["+index[0]+"]"+"["+index[1]+"]");         //
       b.putClientProperty("OWNER", turn);
       Icon ico=new ImageIcon(turn.toString()+".gif");
       b.setIcon(ico);
       b.setEnabled(false);
       boolean result=checkVictoryCondition(index);
       if(result)
       {
        JOptionPane.showMessageDialog(null, "Player "+turn.toString()+" Wins");
        initComponents();
       }
       else
       {
        if(turn==1)
        {
         turn=2;
         statusBar.setText("Player2's Turn");
        }
        else
        {
         turn=1;
         statusBar.setText("Player1's Turn");
        }
       }
       if(count==9)
       {
        JOptionPane.showMessageDialog(null, "Match is a draw!");
        initComponents();
    
       }
    
      }
    
      Integer getOwner(JButton b)
      {
       return (Integer)b.getClientProperty("OWNER");
      }
    
      //PrintButtonMap for Diagnostics
      void printbuttonMap(Integer [][]bMap)
      {
       for(int i=0;i    for(int j=0;j     System.out.print(bMap[i][j]+" ");
        System.out.println("");
       }
      }
    
      boolean checkVictoryCondition(Integer [] index)
      {
       /*Integer[][]buttonMap=new Integer[][] {
         { getOwner(buttons[0][0]),getOwner(buttons[0][1]),getOwner(buttons[0][2])},
         { getOwner(buttons[1][0]),getOwner(buttons[1][1]),getOwner(buttons[1][2])},
         { getOwner(buttons[2][0]),getOwner(buttons[2][1]),getOwner(buttons[2][2])}
       };
    
       printbuttonMap(buttonMap); */
    
       Integer a=index[0];
                    Integer b=index[1];
       int i;
    
       //check row
       for(i=0;i<3;i++)  {
        if(getOwner(buttons[a][i])!=getOwner(buttons[a][b]))
         break;
       }
       if(i==3)
        return true;
    
       //check column
       for(i=0;i<3;i++)  {
        if(getOwner(buttons[i][b])!=getOwner(buttons[a][b]))
         break;
       }
       if(i==3)
        return true;
    
       //check diagonal
       if((a==2&&b==2)||(a==0&&b==0)||(a==1&&b==1)||(a==0&&b==2)||(a==2&&b==0))
       {
        //left diagonal
        for(i=0;i     if(getOwner(buttons[i][i])!=getOwner(buttons[a][b]))
          break;
        if(i==3)
         return true;
    
        //right diagonal
        if((getOwner(buttons[0][2])==getOwner(buttons[a][b]))&&(getOwner(buttons[1][1])==getOwner(buttons[a][b]))&&(getOwner(buttons[2][0])==getOwner(buttons[a][b])))
         return true;
    
        }
    
       return false;
    
      }
     }
    
    
    
     void initComponents()
     {
      for(int i=0;i<3;i++)   
                             for(int j=0;j<3;j++)  {
        buttons[i][j].putClientProperty("INDEX", new Integer[]{i,j});
        buttons[i][j].putClientProperty("OWNER",null);
        buttons[i][j].setIcon(null);
        buttons[i][j].setEnabled(true);
        turn=1;
        count=0;
        statusBar.setText("Player1's Turn");
    
       }
     }
    
    }
    
    class TicTacToe {
    
     public static void main(String[] args) {
      EventQueue.invokeLater(new Runnable(){
       public void run()
       {
        TicTacToeFrame frame=new TicTacToeFrame();
       }
      });
    
     }
    
    }

    该代码非常简单。 香港专业教育学院在按钮中使用两个属性来存储一些信息,用于检查获胜条件。 一个是“ OWNER”属性,它指示哪个用户当前拥有该正方形,而“ INDEX”属性则指示该正方形在网格中的索引(即[1,1],[1,2]…等)一个正方形,将更新OWNER属性,并使用所有按钮的OWNER属性检查victoryCondition。 其余代码不言自明。
    为第二个播放器添加键盘支持是一件非常容易的事。 正如他们所说的…“我把它留作练习”! 哈哈哈 :D 好吧,我真的希望我能花些时间,以便可以为该应用程序添加网络功能。

    干杯,

    史蒂夫。
    -
    我忘记附加将由应用程序使用的图像图标文件。 你可以在这里下载 http://www.mediafire.com/?d7d93v2342dxind 只需将内容提取到包含代码的文件夹中即可。 感谢我的朋友“ Gur Png”告诉我这件事。

    参考:来自我们JCG合作伙伴的 Java TicTacToe   Footy'n'Tech博客上的Steve Robinson。


    翻译自: https://www.javacodegeeks.com/2012/02/java-swing-tic-tac-toe.html

    展开全文
  • 你可能听说过五子棋,但是你不一定知道井字游戏井字游戏是...本项目源码就是一套基于安卓的简单的基于安卓的井字游戏项目源码,本项目只有一个java文件,应该算是最简单的游戏了,想研究一下的朋友可以下载编译一下。
  • 测试项目以创建井字游戏,同时还学习如何使用kubernetes和docker。 所需工具: 带有Spring Boot的Java Docker工具箱 迷你库 PostgreSQL数据库 邮差 HTML 在Windows上设置Docker环境 下载Docker ToolBox并安装。 ...
  • 井字游戏与javascript 您可以将游戏文件下载到文件夹game_tic_tac_toe中。 该代码将从index.html文件开始,然后转到start.html文件。 上面的文件只是一个例子。 index.html中的编码器 index.html是默认文件,它将...
  • java swing游戏 大家好! 哇,自从我在这里发布了东西以来已经有一段时间了! 我必须说我真的很想写东西,我保证我不会再陷入“作家的障碍”。 希望 ..最近两个月发生了很多事情,我有很多话要说。 但是在这篇文章...

    java swing游戏

    大家好! 哇,自从我在这里发布了东西以来已经有一段时间了! 我必须说我真的很想写东西,我保证我不会再陷入“作家的障碍”。 希望 :) ..最近两个月发生了很多事情,我有很多话要说。 但是在这篇文章中,我只是要发布我之前写的一个小应用程序。 它是一个TicTacToe游戏应用程序。 从这个特定的程序中学到的东西不多,但是我真的想摆脱这种僵局,因此我今天就发布这个。

    我实际上写了这段代码是为了向我的一位朋友展示Java的一些非常酷的功能,这些朋友也以“ C ++”风格编写了相同的应用程序。 而且我的那个朋友甚至为计算机播放器开发了代码。 但是在完成他的代码后,他可悲地意识到了一个基本事实,即如果你玩的很好,你将无法在井字游戏中获胜! 呵呵 :D 所以我没有冒险进入那个领域。 老实说,我对编写AI应用程序并不十分感兴趣。 但由于我喜欢网络编程,因此我想到向此应用程序添加网络多人游戏功能。 但是很遗憾,我还没有时间这样做。
    Anywaiz应用程序的工作方式如下-游戏启动后即自动启动,状态栏指示现在轮到哪个玩家,剩下的只是简单的玩法! 在游戏结束时,该应用程序将自动重置。
    进入代码。

    import javax.swing.*;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.util.logging.Logger;
    
    /**
    * TicTacToe Application
    * @author Steve Robinson
    * @version 1.0
    */
    
    class TicTacToeFrame extends JFrame
    {
    
     JButton [][] buttons= new JButton[3][3];
     JTextField statusBar;
     GamePanel panel;
     Integer turn;
     GameListener listener=new GameListener();
     Integer count;
    
     public TicTacToeFrame()
     {
      setLayout(new BorderLayout());
    
      panel=new GamePanel();
      add(panel,BorderLayout.CENTER);
    
      statusBar=new JTextField("Player1's Turn");
      statusBar.setEditable(false);
      add(statusBar,BorderLayout.SOUTH);
    
      setTitle("Tic Tac Toe!");
      setVisible(true);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setBounds(400,400,300,300);
     }
    
     class GamePanel extends JPanel
     {
    
      public GamePanel()
      {
       setLayout(new GridLayout(3,3));
       turn =1;
       count=0;
       for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)   {
         buttons[i][j]=new JButton();
         buttons[i][j].putClientProperty("INDEX", new Integer[]{i,j});
         buttons[i][j].putClientProperty("OWNER", null);
         buttons[i][j].addActionListener(listener);
         add(buttons[i][j]);
        }
      }
     }
    
     class GameListener implements ActionListener
     {
      public void actionPerformed(ActionEvent e)
      {
       count++;
       JButton b=(JButton)e.getSource();
       Integer[]index=(Integer[]) b.getClientProperty("INDEX");
    
       //System.out.println(turn); //turn                  //   //System.out.println("["+index[0]+"]"+"["+index[1]+"]");         //
       b.putClientProperty("OWNER", turn);
       Icon ico=new ImageIcon(turn.toString()+".gif");
       b.setIcon(ico);
       b.setEnabled(false);
       boolean result=checkVictoryCondition(index);
       if(result)
       {
        JOptionPane.showMessageDialog(null, "Player "+turn.toString()+" Wins");
        initComponents();
       }
       else
       {
        if(turn==1)
        {
         turn=2;
         statusBar.setText("Player2's Turn");
        }
        else
        {
         turn=1;
         statusBar.setText("Player1's Turn");
        }
       }
       if(count==9)
       {
        JOptionPane.showMessageDialog(null, "Match is a draw!");
        initComponents();
    
       }
    
      }
    
      Integer getOwner(JButton b)
      {
       return (Integer)b.getClientProperty("OWNER");
      }
    
      //PrintButtonMap for Diagnostics
      void printbuttonMap(Integer [][]bMap)
      {
       for(int i=0;i    for(int j=0;j     System.out.print(bMap[i][j]+" ");
        System.out.println("");
       }
      }
    
      boolean checkVictoryCondition(Integer [] index)
      {
       /*Integer[][]buttonMap=new Integer[][] {
         { getOwner(buttons[0][0]),getOwner(buttons[0][1]),getOwner(buttons[0][2])},
         { getOwner(buttons[1][0]),getOwner(buttons[1][1]),getOwner(buttons[1][2])},
         { getOwner(buttons[2][0]),getOwner(buttons[2][1]),getOwner(buttons[2][2])}
       };
    
       printbuttonMap(buttonMap); */
    
       Integer a=index[0];
                    Integer b=index[1];
       int i;
    
       //check row
       for(i=0;i<3;i++)  {
        if(getOwner(buttons[a][i])!=getOwner(buttons[a][b]))
         break;
       }
       if(i==3)
        return true;
    
       //check column
       for(i=0;i<3;i++)  {
        if(getOwner(buttons[i][b])!=getOwner(buttons[a][b]))
         break;
       }
       if(i==3)
        return true;
    
       //check diagonal
       if((a==2&&b==2)||(a==0&&b==0)||(a==1&&b==1)||(a==0&&b==2)||(a==2&&b==0))
       {
        //left diagonal
        for(i=0;i     if(getOwner(buttons[i][i])!=getOwner(buttons[a][b]))
          break;
        if(i==3)
         return true;
    
        //right diagonal
        if((getOwner(buttons[0][2])==getOwner(buttons[a][b]))&&(getOwner(buttons[1][1])==getOwner(buttons[a][b]))&&(getOwner(buttons[2][0])==getOwner(buttons[a][b])))
         return true;
    
        }
    
       return false;
    
      }
     }
    
    
    
     void initComponents()
     {
      for(int i=0;i<3;i++)   
                             for(int j=0;j<3;j++)  {
        buttons[i][j].putClientProperty("INDEX", new Integer[]{i,j});
        buttons[i][j].putClientProperty("OWNER",null);
        buttons[i][j].setIcon(null);
        buttons[i][j].setEnabled(true);
        turn=1;
        count=0;
        statusBar.setText("Player1's Turn");
    
       }
     }
    
    }
    
    class TicTacToe {
    
     public static void main(String[] args) {
      EventQueue.invokeLater(new Runnable(){
       public void run()
       {
        TicTacToeFrame frame=new TicTacToeFrame();
       }
      });
    
     }
    
    }

    该代码非常简单。 香港专业教育学院在按钮中使用两个属性来存储一些信息,用于检查获胜条件。 一个是“ OWNER”属性,该属性指示哪个用户当前拥有该正方形,而“ INDEX”属性则指示该正方形在网格中的索引(即[1,1],[1,2]…等)一个正方形,将更新OWNER属性,并使用所有按钮的OWNER属性检查victoryCondition。 其余代码不言自明。
    为第二个播放器添加键盘支持是一件非常容易的事。 正如他们所说的…“我把它留作练习”! 哈哈哈 :D 好吧,我真的希望我能花些时间,以便可以为该应用程序添加网络功能。

    干杯,

    史蒂夫。
    -
    我忘记附加将由应用程序使用的图像图标文件。 你可以在这里下载 http://www.mediafire.com/?d7d93v2342dxind 只需将内容提取到包含代码的文件夹中即可。 感谢我的朋友“ Gur Png”告诉我这件事。

    参考:来自我们JCG合作伙伴的 Java TicTacToe   Footy'n'Tech博客上的Steve Robinson。


    翻译自: https://www.javacodegeeks.com/2012/02/java-swing-tic-tac-toe.html

    java swing游戏

    展开全文
  • c#实现井字棋小游戏

    2020-05-11 20:09:51
    c# winform实现井字棋小游戏,可选择人机对战或双人对战,以及谁先谁后。博弈算法使用一层最小最大算法,可实现不输。
  • 井字游戏 井字游戏是使用纯jQuery开发的全功能游戏。 开发者: HTML。 CSS。 JS。 jQuery。 静音特点: 易于开发。 独特、现代、简约且充满活力。 简单的逻辑。 有吸引力的用户界面。 短代码。 项目预览: ...
  • 井字游戏的规则是:在一个井字格子的棋盘里下棋,横竖斜一旦三子连子,则胜。而事实上,遵循一定的规则,该游戏便能保证不败,即至少是平局。 若是两人对战,则仅需要判断“胜负平”三种状态即可,比较简单,而人机...

    井字游戏的规则是:在一个井字格子的棋盘里下棋,横竖斜一旦三子连子,则胜。而事实上,遵循一定的规则,该游戏便能保证不败,即至少是平局。
    若是两人对战,则仅需要判断“胜负平”三种状态即可,比较简单,而人机对战的难点便在于让机器立于不败之地的下棋规则。下面会重点讲解不败的思路。

    先放一张游戏截图,程序演示与源码下载可以去:戳我演示或下载代码
    井字游戏

    在此先规定电脑一定是先手,如果电脑不是先手的话算法需要另外设计,但方法类似,在此暂不讨论。先说说电脑先手时保持不败的设计思路:
    根据下图标出的编号来看:
    这里写图片描述
    前两子是有特别讲究的,不然可能会输。
    第一子:只能在正中间或者四个角随机选一个,即1、3、5、7、9中任选一个。
    第二子:分两种情况讨论。

    1. 若第一子在正中,即5号,那么如果玩家下在四个角(1、3、7、9),则第二子下其对角(9、7、3、1)。如果玩家下在某一行或某一列的中间格,即2、4、6、8的某一个,则第二子应下在靠近其的某个角。
      比如:

      电脑(第1子):5
      玩家(第1子):1
      电脑(第2子):9



      电脑(第1子):5
      玩家(第1子):2
      电脑(第2子):1或3(随机选择)

    2. 若第一子在四个角,即1、3、7、9其中之一,则也许根据玩家的下法来判断。
      若玩家下在正中央,即5号格子,那么第二步就需下第一步的对角,即9、7、3、1。 如果玩家下的不是正中央,那么第二步就下正中央。 举例:

      电脑(第1子):3
      玩家(第1子):5
      电脑(第2子):7



      电脑(第1子):3
      玩家(第1子):9
      电脑(第2子):5

    第二子以后,只需遵循一定规则即可。规则共三条,从第一条开始往下判断即可(注意一定要按顺序!!!)
    1、判断电脑下某处后是否能直接胜出。即电脑下的子是否有二连珠且第三个位置还没有棋子。如果有,就往该处下棋,即可胜出,如果没有,往下。
    2、判断玩家棋子是否有二连珠且对应连线的第三个位置为空位的,如果有,将该空位补上,如果没有,第三步。
    3、遍历所有还没下棋的格子,对每一个格子进行判断,并统计出如果下这一格,能让几条线有二连珠且第三个位置为空位。选择统计的数量最多的一格下棋。有点抽象,拿下图举个例子,图中编号为下棋的顺序:
    这里写图片描述
    看第五步棋,也就是电脑的第三步,如果该棋下在第一行中间位置,能成线的条数为0,如果下在第一列中间位置,成线条数为1(第一列),而下在现在这个位置,成线条数为2(第一列与第三行)。而成线数越多,便越有优势,当成两条线时,便赢了。

    下面放上源代码,核心代码有详细注释,可以直接去上面给的链接里切换编辑视图,点击右下角有地方下载。此处代码也可以直接复制即可运行:
    html

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>YinyouTicTacToe</title>
        <link href="https://fonts.googleapis.com/css?family=Itim" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="css/style.css">
    </head>
    <body>
        <h1>Yinyou TicTacToe</h1>
        <div class="main">
                <div id="tic-1" class="tic">
                    <span id="span-1" class="tic-span"></span>
                </div>
                <div id="tic-2" class="tic">
                    <span id="span-2" class="tic-span"></span>
                </div>
                <div id="tic-3" class="tic">
                    <span id="span-3" class="tic-span"></span>
                </div>
                <div id="tic-4" class="tic">
                    <span id="span-4" class="tic-span"></span>
                </div>
                <div id="tic-5" class="tic">
                    <span id="span-5" class="tic-span"></span>
                </div>
                <div id="tic-6" class="tic">
                    <span id="span-6" class="tic-span"></span>
                </div>
                <div id="tic-7" class="tic">
                    <span id="span-7" class="tic-span"></span>
                </div>
                <div id="tic-8" class="tic">
                    <span id="span-8" class="tic-span"></span>
                </div>
                <div id="tic-9" class="tic">
                    <span id="span-9" class="tic-span"></span>
                </div>  
        </div>
    
        <div class="back"></div>
        <div class="choose">
            <div class="choose-title">
                <h2>TicTacToe</h2>
                <hr>
                <p>Please choose whether you wanna use? × OR O</p>
            </div>
            <div class="choose-bt">
                <button id="cha">×</button>
                <button id="O">o</button>
            </div>
        </div>
    
        <div class="loser">
            Tie!
        </div>
    
        <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
        <script type="text/javascript" src="js/tic.js"></script>
    </body>
    </html>

    css

    *{
        padding: 0;
        margin: 0;
        font-family: 'Itim', cursive;
    }
    html,body{
        background-color: #cb4042;
        width: 100%;
        height: 96%;
        background-position: fixed;
    }
    
    h1{
        text-align: center;
        color: #fff;
        font-size: 2em;
        margin-top: 3%;
    }
    .main{
        width: 486px;
        height: 486px;
        margin: auto;
        margin-top: 3%;
        background-color: #fff;
        text-align: center;
        z-index: 5;
    }
    
    .tic{
        display: inline-block;
        width: 160px;
        height: 160px;
        font-size: 1em;
        -webkit-text-size-adjust:100%;
        border:1px solid #cb4042;
        cursor: pointer;
        float: left;
        color: #000;
        position: relative;
    }
    .tic-span{
        font-size: 3em;
        color: #cb4042;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
    }
    
    .back{
        position: fixed;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: #000;
        opacity: .5;
        z-index: 20;
    }
    
    .choose{
        z-index: 21;
        position: absolute;
        top: 20%;
        left: 0;
        right: 0;
        margin: auto;
        width: 700px;
        color: #fff;
        background-color: #db4d6d;
        border-radius: 10px;
        outline: none;
        display: none;
    }
    
    .choose-title{
        padding-top: 20px;
        text-align: center;
    }
    
    .choose-bt{
        margin-top: 20px;
        margin-bottom: 15px;
        /* text-align: right;
        margin-right: 15px; */
        text-align: center;
    }
    
    .choose-bt button{
        font-family: sans-serif;
        width: 40px;
        height: 40px;
        font-size: 1.5em;
        text-align: center;
        background:#eee;
        border:1px solid #cb4042;
        border-radius: 50%;
        outline: none;
        color: #cb4042;
        margin-left: 50px;
        margin-right: 50px;
        cursor: pointer;
    }
    
    .choose-bt button:hover{
        background-color: #fff;
    }
    
    .loser{
        position: absolute;
        top: 0;
        height: 100%;
        width: 100%;
        text-align: center;
        font-size: 25em;
        z-index: 1;
        color: red;
        display: none;
    }

    js

    $(document).ready(function(){
        var cmpt = "";  //电脑用的
        var user = "";  //用户用的
        var group = [0,0,0,0,0,0,0,0,0];    //记录九个棋格,0表示没下,1表示电脑,2表示玩家
    
        $(".choose").fadeIn(1000);
        $("#cha").on("click",function(){
            $(".choose").fadeOut(1);
            $(".back").fadeOut(1);
            cmpt = "O";
            user = "×";
            pcStep();
        });
        $("#O").on("click",function(){
            $(".choose").fadeOut(1);
            $(".back").fadeOut(1);
            cmpt="×";
            user="O";
            pcStep();
        });
    
        //电脑下棋,只下一步
        var pcStep = function(){
            var step = 0;       //记录当前是电脑下的第几步
            for(var i in group){
                if(group[i] !== 0){
                    //如果某格已经下过了,step++
                    step++;
                }
            }
            if(step %2 !== 0){
                //如果用户还没下,就return
                return;
            }
    
            if(step === 0){
                //如果电脑当前需要下第一步,因为是第一步所以不需要考虑该位置是否被别人下过的问题
                var proStep = [0,2,6,8,4];  //第一步允许下的地方,四个角与中央,这里用的是从0开始
                var posit = parseInt(Math.random()*5,10);       //从0-4中随机生成一个数,作为proStep的下标,即随机选择一个格子下棋
                group[proStep[posit]] = 1;          //电脑下棋
                $("#span-"+(proStep[posit]+1)).html(cmpt);
    
                judge();
                return;
            }
    
            if(step === 2){
                //如果是电脑下的第二步,分两种情况,分别是电脑第一步下了正中和四个角
                if(group[4] === 1){
                    //如果电脑第一步下的正中,又分两种情况,对方下的是四个角还是中间
                    var corStep = [0,2,6,8];    //四个角在group的索引
                    for(var t = 0; t<4;t++){
                        if(group[corStep[t]] === 2){
                            //如果玩家下的是某一个角,那就下他对角
                            var posit = 0;      //这里表示的是电脑要下的位置
                            if(corStep[t] === 0){
                                posit = 8;
                            }else if(corStep[t] === 8){
                                posit = 0;
                            }else if(corStep[t] === 2){
                                posit = 6;
                            }else if(corStep[t] === 6){
                                posit = 2;
                            }
                            posit = parseInt(posit);
                            group[posit] = 1;   //电脑下棋
                            $("#span-"+(posit+1)).html(cmpt);
                            judge();
                            return;
                        }
                    }
                    //电脑下的不是某个角,而是在每一行或列的中间位置,电脑就下一个靠着它的角
                    var posit_g=[0,0];  //如果下在中间,就会有两个角靠着它,随机选一个
                    var posit = 0;              //这就是随机选择之后的位置
                    if(group[1] === 2){
                        posit_g[0] = 0;
                        posit_g[1] = 2;
                    }else if(group[3] === 2){
                        posit_g[0] = 0;
                        posit_g[1] = 6;
                    }else if(group[5] === 2){
                        posit_g[0] = 2;
                        posit_g[1] = 8;
                    }else if(group[7] === 2){
                        posit_g[0] = 6;
                        posit_g[1] = 8;
                    }
                    posit = posit_g[parseInt(Math.random()*2)];
                    posit = parseInt(posit);
                    group[posit] = 1;   //电脑下棋
                    $("#span-"+(posit+1)).html(cmpt);
                    judge();
                    return;
                }else{
                    //如果电脑第一步下的不是正中,而是四个角
                    //分两种情况,如果对方没下正中,那么就下正中,如果对方下了正中,就下第一步的对角
                    if(group[4] === 0){
                        //玩家没下正中,则下正中
                        group[4] = 1;
                        $("#span-5").html(cmpt);
                        judge();
                        return;
                    }
                    //下第一步的对角
                    var posit = 0;  //记录要下的从0起的位置
                    if(group[0] === 1){
                        posit = 8;
                    }else if(group[8] === 1){
                        posit = 0;
                    }else if(group[2] === 1){
                        posit = 6;
                    }else if(group[6] === 1){
                        posit = 2;
                    }
                    posit = parseInt(posit);
                    group[posit] = 1;   //电脑下棋
                    $("#span-"+(posit+1)).html(cmpt);
                    judge();
                    return;
                }
            }
    
            /*如果是第二步以后,分三步
            * 1、判断自己是否可以三连珠,如果可以就连上就赢了
            * 2、判断对方是否可以三连珠,如果有就堵上,不然就输了
            * 3、遍历剩下的还没下的格子,看下在哪一个,能让自己一条线上存在两粒棋子且都能实现三连珠的  这样的线最多      
            */
    
            //第一步
            var first_arr = checkThree(1,group);
            if(first_arr.length !== 0){
                //如果自己可以三连珠
                var posit = first_arr[0];
                posit = parseInt(posit);
                group[posit] = 1;   //电脑下棋
                $("#span-"+(posit+1)).html(cmpt);
                judge();
                return;
            }
            //如果自己不能三连珠,就第二步,检查对方是否能三连珠
            var second_arr = checkThree(2,group);
            if(second_arr.length !== 0){
                //如果对方可以三连珠
                //console.log(second_arr[0]);
                var posit = second_arr[0];
                posit = parseInt(posit);
                group[posit] = 1;   //电脑下棋
                $("#span-"+(posit+1)).html(cmpt);
                judge();
                return;
            }
            //如果自己和对方都不能三连珠,进入第三步
            var third_posit = 0;
            var third_max = -1;
            for(var temp in group){
                if(group[temp] === 0){
                    if(third_max === -1){
                        third_posit = temp;
                        third_max = 0;
                    }
                    var ttt = [].concat(group);
                    ttt[temp] = 1;
                    var temp_arr = checkThree(1,ttt);
                    if(temp_arr.length > third_max){
                        //如果当前点能让更多个连珠,就决定是它了
                        third_max = temp_arr.length;
                        third_posit = temp;
                    }
                }
            }
            group[third_posit] = 1; //电脑下棋
            //这里必须先转成数字,不然会当成字符串相加,会不对
            var wtf = parseInt(third_posit);
            wtf+=1;
            $("#span-"+wtf).html(cmpt);
            judge();
            return;
        };
    
        //检查是否有一点可以三连珠,参数kind如果是1,检查电脑,参数如果是2,检查玩家,如果检查到下某一点可以三连珠,
        //就返回该格从0开始的下标(数组形式,所有情况都在),如果没找到,返回[]
        //参数gp是参考的数组,正常情况下就是group,但是考虑到第三步需要判断每一个格子的,那时候要传一个临时数组了
        var checkThree = function(kind,gp){
            var situ = [];          //用来记录所有需要返回的值
            var allPossible = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];        //记录八条线
            for(var i in allPossible){
                var x = allPossible[i][0];
                var y = allPossible[i][1];
                var z = allPossible[i][2];
                if((gp[x] === kind && gp[y] === kind && gp[z] === 0) || (gp[x] === 0 && gp[y] === kind && gp[z] === kind) || (gp[x] === kind && gp[y] === 0 && gp[z] === kind)){
                    //迭代判断吧,就不复制粘贴了
                    //如果满足上述条件
                    //console.log("Three:"+allPossible[i]);
                    if(gp[x] === 0){
                        situ.push(x);
                        continue;
                    }else if(gp[y] === 0){
                        situ.push(y);
                        continue;
                    }else if(gp[z] === 0){
                        situ.push(z);
                        continue;
                    }
                }
            }
            return situ;
        };
    
    
        //输赢平的结果显示  state取值1,2,3,1表示电脑赢,2表示玩家赢,3表示平局,a,b,c表示连起来的三格
        var result = function(state,a,b,c){
            if(state === 1){
                console.log('lose');
                $(".loser").html("LOSE!");
    
            }else if(state === 2){
                console.log('win');
                $(".loser").html("WIN!");
    
            }else if(state === 3){
                console.log('tie');
                $(".loser").html("TIE!");
    
            }
            if(state !== 3){
                $("#tic-"+a).css("background-color","#877f6c");
                $("#tic-"+b).css("background-color","#877f6c");
                $("#tic-"+c).css("background-color","#877f6c");
            }
            setTimeout(function(){
                if(state !== 3){
                    $("#tic-"+a).css("background-color","#fff");
                    $("#tic-"+b).css("background-color","#fff");
                    $("#tic-"+c).css("background-color","#fff");
                }
                $(".loser").fadeIn(400,function(){
                        setTimeout(function(){
                        beginAgain();
                    },2000);
                });
            },1500);
    
    
    
        };
    
        //出了结果就重新开始
        var beginAgain= function(){
            for(var yyy = 0; yyy < 9;yyy++){
                group[yyy]=0;
                $("#span-"+(yyy+1)).html("");
            }
            $(".loser").fadeOut(1,function(){
                pcStep();
            });
    
        }
    
        //判断输赢与和棋,一共10种情况,8负1平1还没下完
        var judge = function(){
            if(group[0] === group[1] && group[1] === group[2] && group[0]!== 0){
                //第一行连起来了,这样写是因为格子的编号是从0开始,
                result(group[0],1,2,3);
            }else if(group[3] === group[4] && group[4] === group[5] && group[3] !== 0){
                //第二行
                result(group[3],4,5,6);
            }else if(group[6] === group[7] && group[7] === group[8] && group[6] !== 0){
                //第三行
                result(group[6],7,8,9);
            }else if(group[0] === group[3] && group[3] === group[6] && group[0] !== 0){
                //第一列
                result(group[0],1,4,7);
            }else if(group[1] === group[4] && group[4] === group[7] && group[1] !== 0){
                //第二列
                result(group[1],2,5,8);
            }else if(group[2] === group[5] && group[5] === group[8] && group[2] !== 0){
                //第三列
                result(group[2],3,6,9);
            }else if(group[0] === group[4] && group[4] === group[8] && group[0] !== 0){
                //主对角线
                result(group[0],1,5,9);
            }else if(group[2] === group[4] && group[4] === group[6] && group[2] !== 0){
                //次对角线
                result(group[2],3,5,7);
            }else{
                //没分出胜负
                var isTie = true;
                for(var i = 0; i < 9;i++){
                    if(group[i] === 0){
                        //还有格子没下,表示棋还没下完
                        isTie = false;
                    }
                }
                //平局
                if(isTie){
                    result(3,0,0,0);
                }else{
                    var step = 0;       //记录当前是电脑下的第几步
                    for(var i in group){
                        if(group[i] !== 0){
                        //如果某格已经下过了,step++
                            step++;
                        }
                    }
                    if(step %2 === 0 && step !== 0){
                        //如果用户下了,就电脑下
                        pcStep();   
                    }
                }
            }
        };
    
    
        //初始化棋盘点击事件,闭包以获取对应的o
        var initClick = function(i){
            $("#tic-"+i).on("click",function(){
                var step = 0;       //记录当前是下的第几步
                for(var j in group){
                    if(group[j] !== 0){
                        //如果某格已经下过了,step++
                        step++;
                    }
                }
                if(step %2 === 0){
                    //如果电脑还没下,点了也没用
                    return;
                }
    
    
                if(group[i-1] === 0){
                    //如果没下,那么按了才有效,并将之设置为玩家下的,并判断是否和棋或者赢了
                    //console.log("pressed:"+i);
                    //console.log(group);
                    group[i-1] = 2;
                    $("#span-"+i).html(user);
                    judge();
                }
            });
        };
    
        for(var i=1;i<=9;i++){
            initClick(i);       //初始化棋盘点击事件 
        }
    
    
    
    
    });



    欢迎大家加入QQ群一起交流讨论,「吟游」程序人生——YinyouPoet

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,323
精华内容 529
关键字:

井字游戏下载