如何破解三横二竖井桥架字游戏并取得胜

实拍美国两架战斗机高空上用喷气玩井字游戏-在线观看-风行网
全部标记为已读
您暂未收到新消息哦~
安装PC客户端
把想看的剧下载到本地吧~
点击立即下载就可以下载当前视频了哦~
我来说两句
播放:1,020
播放:1,147
播放:472,958
播放:2,549
播放:4,944
播放:5,664
播放:6,389
播放:2,360
播放:4,975
播放:1,907
播放:49,160
播放:9,569
精选视频号
播放:1,865
播放:1,265更多频道内容在这里查看
爱奇艺用户将能永久保存播放记录
过滤短视频
暂无长视频(电视剧、纪录片、动漫、综艺、电影)播放记录,
按住视频可进行拖动
&正在加载...
收藏成功,可进入
查看所有收藏列表
当前浏览器仅支持手动复制代码
视频地址:
flash地址:
html代码:
通用代码:
通用代码可同时支持电脑和移动设备的分享播放
用爱奇艺APP或微信扫一扫,在手机上继续观看
当前播放时间:
一键下载至手机
限爱奇艺安卓6.0以上版本
使用微信扫一扫,扫描左侧二维码,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:
设备搜寻中...
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
连接失败!
请确保您要连接的设备(仅限安卓)登录了同一爱奇艺账号 且安装并开启不低于V6.0以上版本的爱奇艺客户端
部安卓(Android)设备,请点击进行选择
请您在手机端下载爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
其他安装方式:手机浏览器输入短链接http://71.am/udn
下载安装包到本机:
爱奇艺云推送
请您在手机端登录爱奇艺移动APP(仅支持安卓客户端)
使用微信扫一扫,下载爱奇艺移动APP
180秒后更新
打开爱奇艺移动APP,点击“我的-扫一扫”,扫描左侧二维码进行登录
没有安装爱奇艺视频最新客户端?
如何在井字游戏中提高「获胜」几率【有字幕】
正在检测客户端...
您尚未安装客户端,正在为您下载...安装完成后点击按钮即可下载
, 可在设置中重新打开噢!
30秒后自动关闭
如何在井字游戏中提高「获胜」几率【有字幕】">如何在井字游戏中提高「获胜」几率【有字幕】
请选择打赏金额:
播放量12.7万
播放量数据:快去看看谁在和你一起看视频吧~
更多数据:
Copyright (C) 2018 & All Rights Reserved
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制
正在为您下载爱奇艺客户端安装后即可快速下载海量视频
正在为您下载爱奇艺客户端安装后即可免费观看1080P视频
&li data-elem="tabtitle" data-seq="{{seq}}"& &a href="javascript:void(0);"& &span>{{start}}-{{end}}&/span& &/a& &/li&
&li data-downloadSelect-elem="item" data-downloadSelect-selected="false" data-downloadSelect-tvid="{{tvid}}"& &a href="javascript:void(0);"&{{pd}}&/a&
选择您要下载的《
色情低俗内容
血腥暴力内容
广告或欺诈内容
侵犯了我的权力
还可以输入
您使用浏览器不支持直接复制的功能,建议您使用Ctrl+C或右键全选进行地址复制图片与代码可见下载
1.1 &先将游戏界面所需的图片放于“drawable-xxhdpi”文件夹中,后缀xxhdpi表示超高密度。
然后将图片封装到drawable中一个名为tile.xml的文件中
&?xml version="1.0" encoding="utf-8"?&
&level-list xmlns:android="http://schemas.android.com/apk/res/android" &
android:drawable="@drawable/x_blue"
android:maxLevel="0" /&
android:drawable="@drawable/o_red"
android:maxLevel="1" /&
android:drawable="@drawable/tile_empty"
android:maxLevel="2" /&
android:drawable="@drawable/tile_available"
android:maxLevel="3" /&
&/level-list&
每个格子都有4种可能的状态:X、O、空 和 可下。
下面是格子为空时的定义,在文件tile_empty.xml中
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&corners android:radius="@dimen/corner_radius"/&
下面是格子可下时的定义,在文件tile_available.xml中
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&solid android:color="@color/available_color"/&
&corners android:radius="@dimen/corner_radius"/&
1.2 小棋盘
由排列成3×3网格的9个格子组成,通过指定行号和列号确定每个格子的位置。
以下文件是位于layout的small_board.xml
&GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tile_background"
android:elevation="@dimen/elevation_low"
android:padding="@dimen/small_board_padding"
tools:context=".GameActivity"&
&ImageButton android:id="@+id/small1" style="@style/TileButton"
android:layout_column="0" android:layout_row="0"/&
&ImageButton android:id="@+id/small2" style="@style/TileButton"
android:layout_column="1" android:layout_row="0"/&
&ImageButton android:id="@+id/small3" style="@style/TileButton"
android:layout_column="2" android:layout_row="0"/&
&ImageButton android:id="@+id/small4" style="@style/TileButton"
android:layout_column="0" android:layout_row="1"/&
&ImageButton android:id="@+id/small5" style="@style/TileButton"
android:layout_column="1" android:layout_row="1"/&
&ImageButton android:id="@+id/small6" style="@style/TileButton"
android:layout_column="2" android:layout_row="1"/&
&ImageButton android:id="@+id/small7" style="@style/TileButton"
android:layout_column="0" android:layout_row="2"/&
&ImageButton android:id="@+id/small8" style="@style/TileButton"
android:layout_column="1" android:layout_row="2"/&
&ImageButton android:id="@+id/small9" style="@style/TileButton"
android:layout_column="2" android:layout_row="2"/&
&/GridLayout&
修改styles.xml
&?xml version="1.0" encoding="utf-8"?&
&resources&
&!-- Base application theme. --&
&style name="AppTheme"
parent="android:Theme.Holo.Light.NoActionBar.Fullscreen"&
&!-- Customize your theme here. --&
&style name="TileButton"&
&item name="android:layout_width"&@dimen/tile_size&/item&
&item name="android:layout_height"&@dimen/tile_size&/item&
&item name="android:layout_margin"&@dimen/tile_margin&/item&
&item name="android:background"&#&/item&
&item name="android:padding"&@dimen/tile_padding&/item&
&item name="android:scaleType"&centerCrop&/item&
&item name="android:src"&@drawable/tile&/item&
&/resources&
1.3 背景信息
drawable中tile_background.xml的定义如下
&?xml version="1.0" encoding="utf-8"?&
&level-list xmlns:android="http://schemas.android.com/apk/res/android"&
android:drawable="@drawable/tile_blue"
android:maxLevel="0"/&
android:drawable="@drawable/tile_red"
android:maxLevel="1"/&
android:drawable="@drawable/tile_gray"
android:maxLevel="2"/&
android:drawable="@drawable/tile_purple"
android:maxLevel="3"/&
&/level-list&
用蓝色格子表示格子被玩家X占用,红色表示被玩家O占用,灰色表示未被玩家占用,紫色表示被两个玩家占用(即表示两个玩家平手)。分别在tile_blue.xml, &tile_red.xml,&&tile_gray.xml,&&tile_purple.xml 中定义,如下。
&!--blue--&
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&solid android:color="@color/blue_color"/&
&corners android:radius="@dimen/corner_radius"/&
&!--red--&
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&solid android:color="@color/red_color"/&
&corners android:radius="@dimen/corner_radius"/&
&!--gray--&
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&solid android:color="@color/gray_color"/&
&corners android:radius="@dimen/corner_radius"/&
&!--purple--&
&?xml version="1.0" encoding="utf-8"?&
&shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"&
android:width="@dimen/stroke_width"
android:color="@color/dark_border_color"/&
&solid android:color="@color/purple_color"/&
&corners android:radius="@dimen/corner_radius"/&
&1.4 大棋盘
large_board.xml
&GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".GameActivity"&
&include android:id="@+id/large1" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="0" android:layout_row="0"/&
&include android:id="@+id/large2" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="1" android:layout_row="0"/&
&include android:id="@+id/large3" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="2" android:layout_row="0"/&
&include android:id="@+id/large4" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="0" android:layout_row="1"/&
&include android:id="@+id/large5" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="1" android:layout_row="1"/&
&include android:id="@+id/large6" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="2" android:layout_row="1"/&
&include android:id="@+id/large7" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="0" android:layout_row="2"/&
&include android:id="@+id/large8" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="1" android:layout_row="2"/&
&include android:id="@+id/large9" layout="@layout/small_board"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="@dimen/small_board_margin"
android:layout_column="2" android:layout_row="2"/&
&/GridLayout&
&其中&include&用于创建一个由属性layout指定的布局实例,并设置其他属性,再将视图放到父布局的指定位置。
1.5 组合在一起
将整个棋盘封装在一起
&!--fragment_game.xml--&
&RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".GameActivity"&
layout="@layout/large_board"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/&
&/RelativeLayout&
&!--activity_game.xml--&
&FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TicTacToeActivity"&
&ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/sandy_beach"/&
&LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"&
android:id="@+id/fragment_game"
class="org.example.tictactoe.GameFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_game"/&
&!-- Control fragment goes here... --&
&/LinearLayout&
&/FrameLayout&
&2 开始游戏
2.1 将 “开始游戏” 和 “继续游戏” 按钮的功能加入,修改MainFragment.java
package org.example.
import android.app.AlertD
import android.app.F
import android.content.DialogIimport android.os.B
import android.view.LayoutI
import android.view.V
import android.view.ViewG
public class MainFragment extends Fragment {
private AlertDialog mD
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =
inflater.inflate(R.layout.fragment_main, container, false);
// Handle buttons here...
View newButton = rootView.findViewById(R.id.new_button);
View continueButton = rootView.findViewById(R.id.continue_button);
View aboutButton = rootView.findViewById(R.id.about_button);
newButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(getActivity(), GameActivity.class);
getActivity().startActivity(intent);
continueButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(getActivity(), GameActivity.class);
intent.putExtra(GameActivity.KEY_RESTORE, true);
getActivity().startActivity(intent);
aboutButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.about_text);
builder.setCancelable(false);
builder.setPositiveButton(R.string.ok_label,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
// nothing
mDialog = builder.show();
return rootV
public void onPause() {
super.onPause();
// Get rid of the about dialog if it's still up
if (mDialog != null)
mDialog.dismiss();
其中 Intent 为红色, 将鼠标放置该单词上, 使用快捷键Alt + Enter 导入该类。
2.2 编写 GameActivity.java
2.2.1 方法onCreate()在活动启动时被调用。它根据前面创建的XML文件layout/activity_game.xml创建视图。
package org.example.
import android.app.A
import android.app.AlertD
import android.app.D
import android.content.DialogI
import android.os.B
import android.util.L
public class GameActivity extends Activity {
public static final String KEY_RESTORE = "key_restore";
public static final String PREF_RESTORE = "pref_restore";
private GameFragment mGameF
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// 在此处恢复游戏
每次在程序中添加新活动时,都必须修改AndroidManifest.xml以引用它。在application元素末尾添加以下代码。
android:name="org.example.tictactoe.GameActivity"&
&/activity&
2.2.2 继续游戏
继续扩充GameActivity.java 代码
public class GameActivity extends Activity {
//KEY_RESTORE是传递给新活动的标志的名称,用于将棋盘恢复到以前冻结的状态
public static final String KEY_RESTORE = "key_restore";
public static final String PREF_RESTORE = "pref_restore";
private GameFragment mGameF
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
// 此处恢复游戏
//getFragmentManager获取一个指向跟踪所有片段的对象的句柄
//使用findFragmentById获取指向游戏片段的引用
mGameFragment = (GameFragment) getFragmentManager()
.findFragmentById(R.id.fragment_game);
//对Intent实例调用方法getBooleanExtra()以获得KEY_RESTORE的值
boolean restore = getIntent().getBooleanExtra(KEY_RESTORE, false);
//若restore为true,就使用getPreferences()获取指向该活动的Android首项管理器的句柄
//再调用getString()获取PREF_RESTORE的值
if (restore) {
String gameData = getPreferences(MODE_PRIVATE)
.getString(PREF_RESTORE, null);
if (gameData != null) {
//使用putState来修改游戏的状态
mGameFragment.putState(gameData);
Log.d("UT3", "restore = " + restore);
2.2.3 保存游戏
每当有活动不再处于运行状态时,就要保存游戏。在GameActivity.java添加以下方法
protected void onPause() {
super.onPause();
//getState获取游戏数据
String gameData = mGameFragment.getState();
//getPreferences获取指向首选项存储区的句柄,为首选项创建一个编辑器(edit)
//使用键PREF_RESTORE保存游戏数据(putString),并将修改存储到首选项存储区(commit)
getPreferences(MODE_PRIVATE).edit()
.putString(PREF_RESTORE, gameData)
.commit();
// Log.d负责将一条调试消息写入日志
Log.d("UT3", "state = " + gameData);
2.2.4 重新开始游戏
public void restartGame() {
mGameFragment.restartGame();
2.2.5 宣布获胜方
public void reportWinner(final Tile.Owner winner) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.declare_winner, winner));
builder.setCancelable(false);
builder.setPositiveButton(R.string.ok_label,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
final Dialog dialog = builder.create();
dialog.show();
// Reset the board to the initial position
mGameFragment.initGame();
上述代码使用AlterDialog.Builder类创建了一个消息框,其中包含一行文本和一个ok按键。用户点击ok活动将结束,即关闭游戏屏幕返回主菜单。
2.3 编写GameFragment.java
2.3.1 定义
方法onCreateView用于创建视图。
package org.example.
import android.app.F
import android.os.B
import android.util.L
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.ImageB
import java.util.HashS
import java.util.S
public class GameFragment extends Fragment {
//此处定义数据结构
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
// 设备配置发生变化时保留该片段
initGame();
设置所有数据结构
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =
inflater.inflate(R.layout.large_board, container, false);
initViews(rootView);
updateAllTiles();
return rootV
2.3.2 &数据结构
//此处定义数据结构
// mLargeIds和mSmallIds都是常量数组,分别用于将数字映射到小棋盘和格子资源id
static private int mLargeIds[] = {R.id.large1, R.id.large2, R.id.large3,
R.id.large4, R.id.large5, R.id.large6, R.id.large7, R.id.large8,
R.id.large9,};
static private int mSmallIds[] = {R.id.small1, R.id.small2, R.id.small3,
R.id.small4, R.id.small5, R.id.small6, R.id.small7, R.id.small8,
R.id.small9,};
// 以下三个表示不同层级的格子。最顶层有1个,最底层有81个
private Tile mEntireBoard = new Tile(this);
private Tile mLargeTiles[] = new Tile[9];
private Tile mSmallTiles[][] = new Tile[9][9];
// mPlayer 玩家id
private Tile.Owner mPlayer = Tile.Owner.X;
// mAvailable是列表,包含给定时点可下的所有格子
private Set&Tile& mAvailable = new HashSet&Tile&();
// mLastLarge和mLastSmall是最后一步棋的索引
private int mLastL
private int mLastS
2.3.3 初始化游戏
创建片段时,在方法onCreate()中调用了方法initGame(),该方法将所有的数据结构初始化为起始状态。
public void initGame() {
Log.d("UT3", "init game");
mEntireBoard = new Tile(this);
// 创建所有格子
for (int large = 0; large & 9; large++) {
mLargeTiles[large] = new Tile(this);
for (int small = 0; small & 9; small++) {
mSmallTiles[large][small] = new Tile(this);
mLargeTiles[large].setSubTiles(mSmallTiles[large]);
mEntireBoard.setSubTiles(mLargeTiles);
// 设置先下棋子的玩家可下的格子
mLastSmall = -1;
mLastLarge = -1;
setAvailableFromLastMove(mLastSmall);
2.3.4 &初始化视图
private void initViews(View rootView) {
mEntireBoard.setView(rootView);
for (int large = 0; large & 9; large++) {
View outer = rootView.findViewById(mLargeIds[large]);
mLargeTiles[large].setView(outer);
for (int small = 0; small & 9; small++) {
ImageButton inner = (ImageButton) outer.findViewById
(mSmallIds[small]);
final int fLarge =
final int fSmall =
final Tile smallTile = mSmallTiles[large][small];
smallTile.setView(inner);
inner.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (isAvailable(smallTile)) {
makeMove(fLarge, fSmall);
switchTurns();
2.3.5 将棋子下到格子中
每下一个棋子就要判断是否有玩家已取得胜利,若有,则游戏结束宣布winner;若没有,游戏继续。
private void makeMove(int large, int small) {
mLastLarge =
mLastSmall =
Tile smallTile = mSmallTiles[large][small];
Tile largeTile = mLargeTiles[large];
smallTile.setOwner(mPlayer);
setAvailableFromLastMove(small);
Tile.Owner oldWinner = largeTile.getOwner();
Tile.Owner winner = largeTile.findWinner();
if (winner != oldWinner) {
largeTile.setOwner(winner);
winner = mEntireBoard.findWinner();
mEntireBoard.setOwner(winner);
updateAllTiles();
if (winner != Tile.Owner.NEITHER) {
((GameActivity)getActivity()).reportWinner(winner);
2.3.6 让另一个玩家接着下棋
切换mPlayer的值即可。
private void switchTurns() {
mPlayer = mPlayer == Tile.Owner.X ? Tile.Owner.O : Tile
2.3.7 重新开始游戏
public void restartGame() {
initGame();
initViews(getView());
updateAllTiles();
2.3.8 计算可下棋的格子
根据终极版井字游戏的规则,一个玩家下棋后,对手接下来只能在这步棋所处的格子对应的小棋盘中下棋。
// 用于清空可下棋格子列表,以便能够在其中添加格子
private void clearAvailable() {
mAvailable.clear();
// 用于将一个格子加入可下棋格子列表中
private void addAvailable(Tile tile) {
mAvailable.add(tile);
// 用于判断指定的格子是否可下棋
public boolean isAvailable(Tile tile) {
return mAvailable.contains(tile);
private void setAvailableFromLastMove(int small) {
clearAvailable();
// 让目标小棋盘所有空格子都可下棋
if (small != -1) {
for (int dest = 0; dest & 9; dest++) {
Tile tile = mSmallTiles[small][dest];
if (tile.getOwner() == Tile.Owner.NEITHER)
addAvailable(tile);
// 若目标小棋盘没空格子,则令整个棋盘的空格子都可下棋
if (mAvailable.isEmpty()) {
setAllAvailable();
private void setAllAvailable() {
for (int large = 0; large & 9; large++) {
for (int small = 0; small & 9; small++) {
Tile tile = mSmallTiles[large][small];
if (tile.getOwner() == Tile.Owner.NEITHER)
addAvailable(tile);
2.3.9 处理状态
要将游戏当前状态转换为序列化形式存储下来。注意的是,明确每个格子由哪个玩家占领,还必须跟踪上一步棋子,因为接下来判断哪些地方可下棋取决于上一步棋子。
/** 创建包含游戏状态的字符串 */
public String getState() {
StringBuilder builder = new StringBuilder();
builder.append(mLastLarge);
builder.append(',');
builder.append(mLastSmall);
builder.append(',');
for (int large = 0; large & 9; large++) {
for (int small = 0; small & 9; small++) {
builder.append(mSmallTiles[large][small].getOwner().name());
builder.append(',');
return builder.toString();
/** 根据给定的字符串恢复游戏状态 */
public void putState(String gameData) {
String[] fields = gameData.split(",");
int index = 0;
mLastLarge = Integer.parseInt(fields[index++]);
mLastSmall = Integer.parseInt(fields[index++]);
for (int large = 0; large & 9; large++) {
for (int small = 0; small & 9; small++) {
Tile.Owner owner = Tile.Owner.valueOf(fields[index++]);
mSmallTiles[large][small].setOwner(owner);
setAvailableFromLastMove(mLastSmall);
updateAllTiles();
接下来,重新计算可下棋格子列表,并更新所有格子的drawable状态。
private void updateAllTiles() {
mEntireBoard.updateDrawableState();
for (int large = 0; large & 9; large++) {
mLargeTiles[large].updateDrawableState();
for (int small = 0; small & 9; small++) {
mSmallTiles[large][small].updateDrawableState();
2.4 &定义Tile.java
Tile类 表示任何层次的棋盘格子。
2.4.1 Tile类的轮廓
Tile对象包含占据者和视图,还可能包含一系列格子。Tile类包含构造函数Tile,还包含占据者、视图和子格子的获取函数和设置函数。另外,它还包含管理drawale状态的代码以及判断谁是占据者的代码。
package org.example.
import android.graphics.drawable.D
import android.view.V
import android.widget.ImageB
public class Tile {
public enum Owner {
X, O /* letter O */, NEITHER, BOTH
// 这些级别是在drawable中定义的
private static final int LEVEL_X = 0;
private static final int LEVEL_O = 1; // letter O
private static final int LEVEL_BLANK = 2;
private static final int LEVEL_AVAILABLE = 3;
private static final int LEVEL_TIE = 3;
private final GameFragment mG
private Owner mOwner = Owner.NEITHER;
private View mV
private Tile mSubTiles[];
public Tile(GameFragment game) {
this.mGame =
public View getView() {
public void setView(View view) {
this.mView =
public Owner getOwner() {
public void setOwner(Owner owner) {
this.mOwner =
public Tile[] getSubTiles() {
return mSubT
public void setSubTiles(Tile[] subTiles) {
this.mSubTiles = subT
2.4.2 管理drawable状态的代码
// 通过调用getLevel来确定等级,然后根据视图泪习性,对视图背景或drawable调用setLevel
public void updateDrawableState() {
if (mView == null) return;
int level = getLevel();
if (mView.getBackground() != null) {
mView.getBackground().setLevel(level);
if (mView instanceof ImageButton) {
Drawable drawable = ((ImageButton) mView).getDrawable();
drawable.setLevel(level);
private int getLevel() {
int level = LEVEL_BLANK;
switch (mOwner) {
level = LEVEL_X;
case O: // letter O
level = LEVEL_O;
case BOTH:
level = LEVEL_TIE;
case NEITHER:
level = mGame.isAvailable(this) ? LEVEL_AVAILABLE : LEVEL_BLANK;
2.4.3 编写确定占用者的代码
public Owner findWinner() {
// 如果已确定占用者,就返回它
if (getOwner() != Owner.NEITHER)
return getOwner();
int totalX[] = new int[4];
int totalO[] = new int[4];
countCaptures(totalX, totalO);
if (totalX[3] & 0) return Owner.X;
if (totalO[3] & 0) return Owner.O;
// 检查是否平局
int total = 0;
for (int row = 0; row & 3; row++) {
for (int col = 0; col & 3; col++) {
Owner owner = mSubTiles[3 * row + col].getOwner();
if (owner != Owner.NEITHER) total++;
if (total == 9) return Owner.BOTH;
// 未被玩家占用
return Owner.NEITHER;
2.4.4 方法countCaptures()
如果有占用者,就返回他;否则,计算两玩家占据的格子数。若有一个玩家占据了3个连成一条线的格子那么该玩家为占据者;否则检查小棋盘的所有格子是否否不为空。若是,则为平局,返回BOTH;否则,说明未被任何玩家占据,因此返回NEITHER.
private void countCaptures(int totalX[], int totalO[]) {
int capturedX, capturedO;
// 检查是否有一个玩家的3个棋子成一行
for (int row = 0; row & 3; row++) {
capturedX = capturedO = 0;
for (int col = 0; col & 3; col++) {
Owner owner = mSubTiles[3 * row + col].getOwner();
if (owner == Owner.X || owner == Owner.BOTH) capturedX++;
if (owner == Owner.O || owner == Owner.BOTH) capturedO++;
totalX[capturedX]++;
totalO[capturedO]++;
// 检查是否有一个玩家的3个棋子成一列
for (int col = 0; col & 3; col++) {
capturedX = capturedO = 0;
for (int row = 0; row & 3; row++) {
Owner owner = mSubTiles[3 * row + col].getOwner();
if (owner == Owner.X || owner == Owner.BOTH) capturedX++;
if (owner == Owner.O || owner == Owner.BOTH) capturedO++;
totalX[capturedX]++;
totalO[capturedO]++;
// 检查是否有一个玩家的3个棋子成对角线
capturedX = capturedO = 0;
for (int diag = 0; diag & 3; diag++) {
Owner owner = mSubTiles[3 * diag + diag].getOwner();
if (owner == Owner.X || owner == Owner.BOTH) capturedX++;
if (owner == Owner.O || owner == Owner.BOTH) capturedO++;
totalX[capturedX]++;
totalO[capturedO]++;
capturedX = capturedO = 0;
for (int diag = 0; diag & 3; diag++) {
Owner owner = mSubTiles[3 * diag + (2 - diag)].getOwner();
if (owner == Owner.X || owner == Owner.BOTH) capturedX++;
if (owner == Owner.O || owner == Owner.BOTH) capturedO++;
totalX[capturedX]++;
totalO[capturedO]++;
首先,计算各行的X和O的数量,然后计算各列的X和O的数量,最后计算对角线的。结果是通过两个数组返回的:表示玩家X的数组totalX和表示玩家O的数组totalO。
&2.5 控制游戏
玩游戏时,用户可能想重新开始或返回主菜单。以下提供一种返回主菜单的途径。定义在layout中fragment_control.xml
&LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/control_padding"
tools:context=".GameActivity"&
android:id="@+id/button_restart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="@dimen/elevation_low"
android:drawableTop="@drawable/restart"
android:text="@string/restart_label"/&
android:id="@+id/button_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="@dimen/elevation_low"
android:drawableTop="@drawable/home"
android:text="@string/main_menu_label"/&
&/LinearLayout&
其中所用到的图片位于drawable-xxhdpi中。接下来,要在activity_game.xml中包含一个新片段
android:id="@+id/fragment_game_controls"
class="org.example.tictactoe.ControlFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_control"/&
最后,要编写处理该布局的代码ControlFragment.java
package org.example.
import android.app.F
import android.os.B
import android.view.LayoutI
import android.view.V
import android.view.ViewG
public class ControlFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =
inflater.inflate(R.layout.fragment_control, container, false);
View main = rootView.findViewById(R.id.button_main);
View restart = rootView.findViewById(R.id.button_restart);
main.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getActivity().finish();
restart.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
((GameActivity) getActivity()).restartGame();
return rootV
通过Main Menu按钮结束当前活动,与返回按钮效果相同。Restart按钮假定控制片段嵌入在GameActivity中,因此会将当前活动转换为GameActivity,并调用前面定义的重新开始游戏的方法。
2.6 参数定义
以下定义程序所使用的一些参数。
&!-- dimens.xml--&
&dimen name="activity_horizontal_margin"&8dp&/dimen&
&dimen name="activity_vertical_margin"&8dp&/dimen&
&dimen name="tile_size"&30dp&/dimen&
&dimen name="tile_margin"&0dp&/dimen&
&dimen name="tile_padding"&3dp&/dimen&
&dimen name="control_padding"&20dp&/dimen&
&dimen name="small_board_padding"&2dp&/dimen&
&dimen name="small_board_margin"&2dp&/dimen&
&dimen name="elevation_low"&4dp&/dimen&
&!-- colors.xml --&
&color name="dark_border_color"&#4f4f4f&/color&
&color name="available_color"&#7fbf7f&/color&
&color name="blue_color"&#7f7fff&/color&
&color name="gray_color"&#bfbfbf&/color&
&color name="purple_color"&#7f007f&/color&
&color name="red_color"&#ff7f7f&/color&
&!-- strings.xml --&
&string name="restart_label"&Restart&/string&
&string name="main_menu_label"&Main Menu&/string&
&string name="declare_winner"&%1$s is the winner&/string&
定义横向模式,即不同版本的activity_game.xml 和 fragment_control.xml , 存储在res/layout-land中,-land表示横向模式。
&!-- activity_game.xml --&
&FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TicTacToeActivity"&
&ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/sandy_beach"/&
&LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:baselineAligned="false"
android:orientation="horizontal"&
android:id="@+id/fragment_game"
class="org.example.tictactoe.GameFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_game"/&
android:id="@+id/fragment_game_controls"
class="org.example.tictactoe.ControlFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:layout="@layout/fragment_control"/&
&/LinearLayout&
&/FrameLayout&
&!-- fragment_control.xml --&
&LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/control_padding"
tools:context=".GameActivity"&
android:id="@+id/button_restart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableTop="@drawable/restart"
android:elevation="@dimen/elevation_low"
android:text="@string/restart_label"/&
android:id="@+id/button_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableTop="@drawable/home"
android:elevation="@dimen/elevation_low"
android:text="@string/main_menu_label"/&
&/LinearLayout&
&然后,就可以运行了。
摘自《Hello, Android》
阅读(...) 评论()}

我要回帖

更多关于 电缆竖井桥架图片 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信