]> nv-tegra.nvidia Code Review - android/platform/tools/build.git/blob - samples/tictactoe/lib/src/main/java/com/example/android/tictactoe/library/GameActivity.java
Merge "Refactor the gradle plugin."
[android/platform/tools/build.git] / samples / tictactoe / lib / src / main / java / com / example / android / tictactoe / library / GameActivity.java
1 /*\r
2  * Copyright (C) 2010 The Android Open Source Project\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.example.android.tictactoe.library;\r
18 \r
19 import java.util.Random;\r
20 \r
21 import android.app.Activity;\r
22 import android.os.Bundle;\r
23 import android.os.Handler;\r
24 import android.os.Message;\r
25 import android.os.Handler.Callback;\r
26 import android.view.View;\r
27 import android.view.View.OnClickListener;\r
28 import android.widget.Button;\r
29 import android.widget.TextView;\r
30 \r
31 import com.example.android.tictactoe.library.GameView.ICellListener;\r
32 import com.example.android.tictactoe.library.GameView.State;\r
33 \r
34 \r
35 public class GameActivity extends Activity {\r
36 \r
37     /** Start player. Must be 1 or 2. Default is 1. */\r
38     public static final String EXTRA_START_PLAYER =\r
39         "com.example.android.tictactoe.library.GameActivity.EXTRA_START_PLAYER";\r
40 \r
41     private static final int MSG_COMPUTER_TURN = 1;\r
42     private static final long COMPUTER_DELAY_MS = 500;\r
43 \r
44     private Handler mHandler = new Handler(new MyHandlerCallback());\r
45     private Random mRnd = new Random();\r
46     private GameView mGameView;\r
47     private TextView mInfoView;\r
48     private Button mButtonNext;\r
49 \r
50     /** Called when the activity is first created. */\r
51     @Override\r
52     public void onCreate(Bundle bundle) {\r
53         super.onCreate(bundle);\r
54 \r
55         /*\r
56          * IMPORTANT: all resource IDs from this library will eventually be merged\r
57          * with the resources from the main project that will use the library.\r
58          *\r
59          * If the main project and the libraries define the same resource IDs,\r
60          * the application project will always have priority and override library resources\r
61          * and IDs defined in multiple libraries are resolved based on the libraries priority\r
62          * defined in the main project.\r
63          *\r
64          * An intentional consequence is that the main project can override some resources\r
65          * from the library.\r
66          * (TODO insert example).\r
67          *\r
68          * To avoid potential conflicts, it is suggested to add a prefix to the\r
69          * library resource names.\r
70          */\r
71         setContentView(R.layout.lib_game);\r
72 \r
73         mGameView = (GameView) findViewById(R.id.game_view);\r
74         mInfoView = (TextView) findViewById(R.id.info_turn);\r
75         mButtonNext = (Button) findViewById(R.id.next_turn);\r
76 \r
77         mGameView.setFocusable(true);\r
78         mGameView.setFocusableInTouchMode(true);\r
79         mGameView.setCellListener(new MyCellListener());\r
80 \r
81         mButtonNext.setOnClickListener(new MyButtonListener());\r
82     }\r
83 \r
84     @Override\r
85     protected void onResume() {\r
86         super.onResume();\r
87 \r
88         State player = mGameView.getCurrentPlayer();\r
89         if (player == State.UNKNOWN) {\r
90             player = State.fromInt(getIntent().getIntExtra(EXTRA_START_PLAYER, 1));\r
91             if (!checkGameFinished(player)) {\r
92                 selectTurn(player);\r
93             }\r
94         }\r
95         if (player == State.PLAYER2) {\r
96             mHandler.sendEmptyMessageDelayed(MSG_COMPUTER_TURN, COMPUTER_DELAY_MS);\r
97         }\r
98         if (player == State.WIN) {\r
99             setWinState(mGameView.getWinner());\r
100         }\r
101     }\r
102 \r
103 \r
104     private State selectTurn(State player) {\r
105         mGameView.setCurrentPlayer(player);\r
106         mButtonNext.setEnabled(false);\r
107 \r
108         if (player == State.PLAYER1) {\r
109             mInfoView.setText(R.string.player1_turn);\r
110             mGameView.setEnabled(true);\r
111 \r
112         } else if (player == State.PLAYER2) {\r
113             mInfoView.setText(R.string.player2_turn);\r
114             mGameView.setEnabled(false);\r
115         }\r
116 \r
117         return player;\r
118     }\r
119 \r
120     private class MyCellListener implements ICellListener {\r
121         public void onCellSelected() {\r
122             if (mGameView.getCurrentPlayer() == State.PLAYER1) {\r
123                 int cell = mGameView.getSelection();\r
124                 mButtonNext.setEnabled(cell >= 0);\r
125             }\r
126         }\r
127     }\r
128 \r
129     private class MyButtonListener implements OnClickListener {\r
130 \r
131         public void onClick(View v) {\r
132             State player = mGameView.getCurrentPlayer();\r
133 \r
134             if (player == State.WIN) {\r
135                 GameActivity.this.finish();\r
136 \r
137             } else if (player == State.PLAYER1) {\r
138                 int cell = mGameView.getSelection();\r
139                 if (cell >= 0) {\r
140                     mGameView.stopBlink();\r
141                     mGameView.setCell(cell, player);\r
142                     finishTurn();\r
143                 }\r
144             }\r
145         }\r
146     }\r
147 \r
148     private class MyHandlerCallback implements Callback {\r
149         public boolean handleMessage(Message msg) {\r
150             if (msg.what == MSG_COMPUTER_TURN) {\r
151 \r
152                 // Pick a non-used cell at random. That's about all the AI you need for this game.\r
153                 State[] data = mGameView.getData();\r
154                 int used = 0;\r
155                 while (used != 0x1F) {\r
156                     int index = mRnd.nextInt(9);\r
157                     if (((used >> index) & 1) == 0) {\r
158                         used |= 1 << index;\r
159                         if (data[index] == State.EMPTY) {\r
160                             mGameView.setCell(index, mGameView.getCurrentPlayer());\r
161                             break;\r
162                         }\r
163                     }\r
164                 }\r
165 \r
166                 finishTurn();\r
167                 return true;\r
168             }\r
169             return false;\r
170         }\r
171     }\r
172 \r
173     private State getOtherPlayer(State player) {\r
174         return player == State.PLAYER1 ? State.PLAYER2 : State.PLAYER1;\r
175     }\r
176 \r
177     private void finishTurn() {\r
178         State player = mGameView.getCurrentPlayer();\r
179         if (!checkGameFinished(player)) {\r
180             player = selectTurn(getOtherPlayer(player));\r
181             if (player == State.PLAYER2) {\r
182                 mHandler.sendEmptyMessageDelayed(MSG_COMPUTER_TURN, COMPUTER_DELAY_MS);\r
183             }\r
184         }\r
185     }\r
186 \r
187     public boolean checkGameFinished(State player) {\r
188         State[] data = mGameView.getData();\r
189         boolean full = true;\r
190 \r
191         int col = -1;\r
192         int row = -1;\r
193         int diag = -1;\r
194 \r
195         // check rows\r
196         for (int j = 0, k = 0; j < 3; j++, k += 3) {\r
197             if (data[k] != State.EMPTY && data[k] == data[k+1] && data[k] == data[k+2]) {\r
198                 row = j;\r
199             }\r
200             if (full && (data[k] == State.EMPTY ||\r
201                          data[k+1] == State.EMPTY ||\r
202                          data[k+2] == State.EMPTY)) {\r
203                 full = false;\r
204             }\r
205         }\r
206 \r
207         // check columns\r
208         for (int i = 0; i < 3; i++) {\r
209             if (data[i] != State.EMPTY && data[i] == data[i+3] && data[i] == data[i+6]) {\r
210                 col = i;\r
211             }\r
212         }\r
213 \r
214         // check diagonals\r
215         if (data[0] != State.EMPTY && data[0] == data[1+3] && data[0] == data[2+6]) {\r
216             diag = 0;\r
217         } else  if (data[2] != State.EMPTY && data[2] == data[1+3] && data[2] == data[0+6]) {\r
218             diag = 1;\r
219         }\r
220 \r
221         if (col != -1 || row != -1 || diag != -1) {\r
222             setFinished(player, col, row, diag);\r
223             return true;\r
224         }\r
225 \r
226         // if we get here, there's no winner but the board is full.\r
227         if (full) {\r
228             setFinished(State.EMPTY, -1, -1, -1);\r
229             return true;\r
230         }\r
231         return false;\r
232     }\r
233 \r
234     private void setFinished(State player, int col, int row, int diagonal) {\r
235 \r
236         mGameView.setCurrentPlayer(State.WIN);\r
237         mGameView.setWinner(player);\r
238         mGameView.setEnabled(false);\r
239         mGameView.setFinished(col, row, diagonal);\r
240 \r
241         setWinState(player);\r
242     }\r
243 \r
244     private void setWinState(State player) {\r
245         mButtonNext.setEnabled(true);\r
246         mButtonNext.setText("Back");\r
247 \r
248         String text;\r
249 \r
250         if (player == State.EMPTY) {\r
251             text = getString(R.string.tie);\r
252         } else if (player == State.PLAYER1) {\r
253             text = getString(R.string.player1_win);\r
254         } else {\r
255             text = getString(R.string.player2_win);\r
256         }\r
257         mInfoView.setText(text);\r
258     }\r
259 }\r