Mega Code Archive

 
Categories / Android / Game
 

TicTacToe Game

// //src\com\example\android\tictactoe\library\GameActivity.java /*  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package com.example.android.tictactoe.library; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Handler.Callback; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.example.android.tictactoe.library.GameView.ICellListener; import com.example.android.tictactoe.library.GameView.State; public class GameActivity extends Activity {     /** Start player. Must be 1 or 2. Default is 1. */     public static final String EXTRA_START_PLAYER =         "com.example.android.tictactoe.library.GameActivity.EXTRA_START_PLAYER";     private static final int MSG_COMPUTER_TURN = 1;     private static final long COMPUTER_DELAY_MS = 500;     private Handler mHandler = new Handler(new MyHandlerCallback());     private Random mRnd = new Random();     private GameView mGameView;     private TextView mInfoView;     private Button mButtonNext;     /** Called when the activity is first created. */     @Override     public void onCreate(Bundle bundle) {         super.onCreate(bundle);         /*          * IMPORTANT: all resource IDs from this library will eventually be merged          * with the resources from the main project that will use the library.          *          * If the main project and the libraries define the same resource IDs,          * the application project will always have priority and override library resources          * and IDs defined in multiple libraries are resolved based on the libraries priority          * defined in the main project.          *          * An intentional consequence is that the main project can override some resources          * from the library.          * (TODO insert example).          *          * To avoid potential conflicts, it is suggested to add a prefix to the          * library resource names.          */         setContentView(R.layout.lib_game);         mGameView = (GameView) findViewById(R.id.game_view);         mInfoView = (TextView) findViewById(R.id.info_turn);         mButtonNext = (Button) findViewById(R.id.next_turn);         mGameView.setFocusable(true);         mGameView.setFocusableInTouchMode(true);         mGameView.setCellListener(new MyCellListener());         mButtonNext.setOnClickListener(new MyButtonListener());     }     @Override     protected void onResume() {         super.onResume();         State player = mGameView.getCurrentPlayer();         if (player == State.UNKNOWN) {             player = State.fromInt(getIntent().getIntExtra(EXTRA_START_PLAYER, 1));             if (!checkGameFinished(player)) {                 selectTurn(player);             }         }         if (player == State.PLAYER2) {             mHandler.sendEmptyMessageDelayed(MSG_COMPUTER_TURN, COMPUTER_DELAY_MS);         }         if (player == State.WIN) {             setWinState(mGameView.getWinner());         }     }     private State selectTurn(State player) {         mGameView.setCurrentPlayer(player);         mButtonNext.setEnabled(false);         if (player == State.PLAYER1) {             mInfoView.setText(R.string.player1_turn);             mGameView.setEnabled(true);         } else if (player == State.PLAYER2) {             mInfoView.setText(R.string.player2_turn);             mGameView.setEnabled(false);         }         return player;     }     private class MyCellListener implements ICellListener {         public void onCellSelected() {             if (mGameView.getCurrentPlayer() == State.PLAYER1) {                 int cell = mGameView.getSelection();                 mButtonNext.setEnabled(cell >= 0);             }         }     }     private class MyButtonListener implements OnClickListener {         public void onClick(View v) {             State player = mGameView.getCurrentPlayer();             if (player == State.WIN) {                 GameActivity.this.finish();             } else if (player == State.PLAYER1) {                 int cell = mGameView.getSelection();                 if (cell >= 0) {                     mGameView.stopBlink();                     mGameView.setCell(cell, player);                     finishTurn();                 }             }         }     }     private class MyHandlerCallback implements Callback {         public boolean handleMessage(Message msg) {             if (msg.what == MSG_COMPUTER_TURN) {                 // Pick a non-used cell at random. That's about all the AI you need for this game.                 State[] data = mGameView.getData();                 int used = 0;                 while (used != 0x1F) {                     int index = mRnd.nextInt(9);                     if (((used >> index) & 1) == 0) {                         used |= 1 << index;                         if (data[index] == State.EMPTY) {                             mGameView.setCell(index, mGameView.getCurrentPlayer());                             break;                         }                     }                 }                 finishTurn();                 return true;             }             return false;         }     }     private State getOtherPlayer(State player) {         return player == State.PLAYER1 ? State.PLAYER2 : State.PLAYER1;     }     private void finishTurn() {         State player = mGameView.getCurrentPlayer();         if (!checkGameFinished(player)) {             player = selectTurn(getOtherPlayer(player));             if (player == State.PLAYER2) {                 mHandler.sendEmptyMessageDelayed(MSG_COMPUTER_TURN, COMPUTER_DELAY_MS);             }         }     }     public boolean checkGameFinished(State player) {         State[] data = mGameView.getData();         boolean full = true;         int col = -1;         int row = -1;         int diag = -1;         // check rows         for (int j = 0, k = 0; j < 3; j++, k += 3) {             if (data[k] != State.EMPTY && data[k] == data[k+1] && data[k] == data[k+2]) {                 row = j;             }             if (full && (data[k] == State.EMPTY ||                          data[k+1] == State.EMPTY ||                          data[k+2] == State.EMPTY)) {                 full = false;             }         }         // check columns         for (int i = 0; i < 3; i++) {             if (data[i] != State.EMPTY && data[i] == data[i+3] && data[i] == data[i+6]) {                 col = i;             }         }         // check diagonals         if (data[0] != State.EMPTY && data[0] == data[1+3] && data[0] == data[2+6]) {             diag = 0;         } else  if (data[2] != State.EMPTY && data[2] == data[1+3] && data[2] == data[0+6]) {             diag = 1;         }         if (col != -1 || row != -1 || diag != -1) {             setFinished(player, col, row, diag);             return true;         }         // if we get here, there's no winner but the board is full.         if (full) {             setFinished(State.EMPTY, -1, -1, -1);             return true;         }         return false;     }     private void setFinished(State player, int col, int row, int diagonal) {         mGameView.setCurrentPlayer(State.WIN);         mGameView.setWinner(player);         mGameView.setEnabled(false);         mGameView.setFinished(col, row, diagonal);         setWinState(player);     }     private void setWinState(State player) {         mButtonNext.setEnabled(true);         mButtonNext.setText("Back");         String text;         if (player == State.EMPTY) {             text = getString(R.string.tie);         } else if (player == State.PLAYER1) {             text = getString(R.string.player1_win);         } else {             text = getString(R.string.player2_win);         }         mInfoView.setText(text);     } } //src\com\example\android\tictactoe\library\GameView.java /*  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package com.example.android.tictactoe.library; import java.util.Random; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory.Options; import android.graphics.Paint.Style; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.os.Handler.Callback; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; //----------------------------------------------- public class GameView extends View {     public static final long FPS_MS = 1000/2;     public enum State {         UNKNOWN(-3),         WIN(-2),         EMPTY(0),         PLAYER1(1),         PLAYER2(2);         private int mValue;         private State(int value) {             mValue = value;         }         public int getValue() {             return mValue;         }         public static State fromInt(int i) {             for (State s : values()) {                 if (s.getValue() == i) {                     return s;                 }             }             return EMPTY;         }     }     private static final int MARGIN = 4;     private static final int MSG_BLINK = 1;     private final Handler mHandler = new Handler(new MyHandler());     private final Rect mSrcRect = new Rect();     private final Rect mDstRect = new Rect();     private int mSxy;     private int mOffetX;     private int mOffetY;     private Paint mWinPaint;     private Paint mLinePaint;     private Paint mBmpPaint;     private Bitmap mBmpPlayer1;     private Bitmap mBmpPlayer2;     private Drawable mDrawableBg;     private ICellListener mCellListener;     /** Contains one of {@link State#EMPTY}, {@link State#PLAYER1} or {@link State#PLAYER2}. */     private final State[] mData = new State[9];     private int mSelectedCell = -1;     private State mSelectedValue = State.EMPTY;     private State mCurrentPlayer = State.UNKNOWN;     private State mWinner = State.EMPTY;     private int mWinCol = -1;     private int mWinRow = -1;     private int mWinDiag = -1;     private boolean mBlinkDisplayOff;     private final Rect mBlinkRect = new Rect();     public interface ICellListener {         abstract void onCellSelected();     }     public GameView(Context context, AttributeSet attrs) {         super(context, attrs);         requestFocus();         mDrawableBg = getResources().getDrawable(R.drawable.lib_bg);         setBackgroundDrawable(mDrawableBg);         mBmpPlayer1 = getResBitmap(R.drawable.lib_cross);         mBmpPlayer2 = getResBitmap(R.drawable.lib_circle);         if (mBmpPlayer1 != null) {             mSrcRect.set(0, 0, mBmpPlayer1.getWidth() -1, mBmpPlayer1.getHeight() - 1);         }         mBmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);         mLinePaint = new Paint();         mLinePaint.setColor(0xFFFFFFFF);         mLinePaint.setStrokeWidth(5);         mLinePaint.setStyle(Style.STROKE);         mWinPaint = new Paint(Paint.ANTI_ALIAS_FLAG);         mWinPaint.setColor(0xFFFF0000);         mWinPaint.setStrokeWidth(10);         mWinPaint.setStyle(Style.STROKE);         for (int i = 0; i < mData.length; i++) {             mData[i] = State.EMPTY;         }         if (isInEditMode()) {             // In edit mode (e.g. in the Eclipse ADT graphical layout editor)             // we'll use some random data to display the state.             Random rnd = new Random();             for (int i = 0; i < mData.length; i++) {                 mData[i] = State.fromInt(rnd.nextInt(3));             }         }     }     public State[] getData() {         return mData;     }     public void setCell(int cellIndex, State value) {         mData[cellIndex] = value;         invalidate();     }     public void setCellListener(ICellListener cellListener) {         mCellListener = cellListener;     }     public int getSelection() {         if (mSelectedValue == mCurrentPlayer) {             return mSelectedCell;         }         return -1;     }     public State getCurrentPlayer() {         return mCurrentPlayer;     }     public void setCurrentPlayer(State player) {         mCurrentPlayer = player;         mSelectedCell = -1;     }     public State getWinner() {         return mWinner;     }     public void setWinner(State winner) {         mWinner = winner;     }     /** Sets winning mark on specified column or row (0..2) or diagonal (0..1). */     public void setFinished(int col, int row, int diagonal) {         mWinCol = col;         mWinRow = row;         mWinDiag = diagonal;     }     //-----------------------------------------     @Override     protected void onDraw(Canvas canvas) {         super.onDraw(canvas);         int sxy = mSxy;         int s3  = sxy * 3;         int x7 = mOffetX;         int y7 = mOffetY;         for (int i = 0, k = sxy; i < 2; i++, k += sxy) {             canvas.drawLine(x7    , y7 + k, x7 + s3 - 1, y7 + k     , mLinePaint);             canvas.drawLine(x7 + k, y7    , x7 + k     , y7 + s3 - 1, mLinePaint);         }         for (int j = 0, k = 0, y = y7; j < 3; j++, y += sxy) {             for (int i = 0, x = x7; i < 3; i++, k++, x += sxy) {                 mDstRect.offsetTo(MARGIN+x, MARGIN+y);                 State v;                 if (mSelectedCell == k) {                     if (mBlinkDisplayOff) {                         continue;                     }                     v = mSelectedValue;                 } else {                     v = mData[k];                 }                 switch(v) {                 case PLAYER1:                     if (mBmpPlayer1 != null) {                         canvas.drawBitmap(mBmpPlayer1, mSrcRect, mDstRect, mBmpPaint);                     }                     break;                 case PLAYER2:                     if (mBmpPlayer2 != null) {                         canvas.drawBitmap(mBmpPlayer2, mSrcRect, mDstRect, mBmpPaint);                     }                     break;                 }             }         }         if (mWinRow >= 0) {             int y = y7 + mWinRow * sxy + sxy / 2;             canvas.drawLine(x7 + MARGIN, y, x7 + s3 - 1 - MARGIN, y, mWinPaint);         } else if (mWinCol >= 0) {             int x = x7 + mWinCol * sxy + sxy / 2;             canvas.drawLine(x, y7 + MARGIN, x, y7 + s3 - 1 - MARGIN, mWinPaint);         } else if (mWinDiag == 0) {             // diagonal 0 is from (0,0) to (2,2)             canvas.drawLine(x7 + MARGIN, y7 + MARGIN,                     x7 + s3 - 1 - MARGIN, y7 + s3 - 1 - MARGIN, mWinPaint);         } else if (mWinDiag == 1) {             // diagonal 1 is from (0,2) to (2,0)             canvas.drawLine(x7 + MARGIN, y7 + s3 - 1 - MARGIN,                     x7 + s3 - 1 - MARGIN, y7 + MARGIN, mWinPaint);         }     }     @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         // Keep the view squared         int w = MeasureSpec.getSize(widthMeasureSpec);         int h = MeasureSpec.getSize(heightMeasureSpec);         int d = w == 0 ? h : h == 0 ? w : w < h ? w : h;         setMeasuredDimension(d, d);     }     @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         int sx = (w - 2 * MARGIN) / 3;         int sy = (h - 2 * MARGIN) / 3;         int size = sx < sy ? sx : sy;         mSxy = size;         mOffetX = (w - 3 * size) / 2;         mOffetY = (h - 3 * size) / 2;         mDstRect.set(MARGIN, MARGIN, size - MARGIN, size - MARGIN);     }     @Override     public boolean onTouchEvent(MotionEvent event) {         int action = event.getAction();         if (action == MotionEvent.ACTION_DOWN) {             return true;         } else if (action == MotionEvent.ACTION_UP) {             int x = (int) event.getX();             int y = (int) event.getY();             int sxy = mSxy;             x = (x - MARGIN) / sxy;             y = (y - MARGIN) / sxy;             if (isEnabled() && x >= 0 && x < 3 && y >= 0 & y < 3) {                 int cell = x + 3 * y;                 State state = cell == mSelectedCell ? mSelectedValue : mData[cell];                 state = state == State.EMPTY ? mCurrentPlayer : State.EMPTY;                 stopBlink();                 mSelectedCell = cell;                 mSelectedValue = state;                 mBlinkDisplayOff = false;                 mBlinkRect.set(MARGIN + x * sxy, MARGIN + y * sxy,                                MARGIN + (x + 1) * sxy, MARGIN + (y + 1) * sxy);                 if (state != State.EMPTY) {                     // Start the blinker                     mHandler.sendEmptyMessageDelayed(MSG_BLINK, FPS_MS);                 }                 if (mCellListener != null) {                     mCellListener.onCellSelected();                 }             }             return true;         }         return false;     }     public void stopBlink() {         boolean hadSelection = mSelectedCell != -1 && mSelectedValue != State.EMPTY;         mSelectedCell = -1;         mSelectedValue = State.EMPTY;         if (!mBlinkRect.isEmpty()) {             invalidate(mBlinkRect);         }         mBlinkDisplayOff = false;         mBlinkRect.setEmpty();         mHandler.removeMessages(MSG_BLINK);         if (hadSelection && mCellListener != null) {             mCellListener.onCellSelected();         }     }     @Override     protected Parcelable onSaveInstanceState() {         Bundle b = new Bundle();         Parcelable s = super.onSaveInstanceState();         b.putParcelable("gv_super_state", s);         b.putBoolean("gv_en", isEnabled());         int[] data = new int[mData.length];         for (int i = 0; i < data.length; i++) {             data[i] = mData[i].getValue();         }         b.putIntArray("gv_data", data);         b.putInt("gv_sel_cell", mSelectedCell);         b.putInt("gv_sel_val",  mSelectedValue.getValue());         b.putInt("gv_curr_play", mCurrentPlayer.getValue());         b.putInt("gv_winner", mWinner.getValue());         b.putInt("gv_win_col", mWinCol);         b.putInt("gv_win_row", mWinRow);         b.putInt("gv_win_diag", mWinDiag);         b.putBoolean("gv_blink_off", mBlinkDisplayOff);         b.putParcelable("gv_blink_rect", mBlinkRect);         return b;     }     @Override     protected void onRestoreInstanceState(Parcelable state) {         if (!(state instanceof Bundle)) {             // Not supposed to happen.             super.onRestoreInstanceState(state);             return;         }         Bundle b = (Bundle) state;         Parcelable superState = b.getParcelable("gv_super_state");         setEnabled(b.getBoolean("gv_en", true));         int[] data = b.getIntArray("gv_data");         if (data != null && data.length == mData.length) {             for (int i = 0; i < data.length; i++) {                 mData[i] = State.fromInt(data[i]);             }         }         mSelectedCell = b.getInt("gv_sel_cell", -1);         mSelectedValue = State.fromInt(b.getInt("gv_sel_val", State.EMPTY.getValue()));         mCurrentPlayer = State.fromInt(b.getInt("gv_curr_play", State.EMPTY.getValue()));         mWinner = State.fromInt(b.getInt("gv_winner", State.EMPTY.getValue()));         mWinCol = b.getInt("gv_win_col", -1);         mWinRow = b.getInt("gv_win_row", -1);         mWinDiag = b.getInt("gv_win_diag", -1);         mBlinkDisplayOff = b.getBoolean("gv_blink_off", false);         Rect r = b.getParcelable("gv_blink_rect");         if (r != null) {             mBlinkRect.set(r);         }         // let the blink handler decide if it should blink or not         mHandler.sendEmptyMessage(MSG_BLINK);         super.onRestoreInstanceState(superState);     }     //-----     private class MyHandler implements Callback {         public boolean handleMessage(Message msg) {             if (msg.what == MSG_BLINK) {                 if (mSelectedCell >= 0 && mSelectedValue != State.EMPTY && mBlinkRect.top != 0) {                     mBlinkDisplayOff = !mBlinkDisplayOff;                     invalidate(mBlinkRect);                     if (!mHandler.hasMessages(MSG_BLINK)) {                         mHandler.sendEmptyMessageDelayed(MSG_BLINK, FPS_MS);                     }                 }                 return true;             }             return false;         }     }     private Bitmap getResBitmap(int bmpResId) {         Options opts = new Options();         opts.inDither = false;         Resources res = getResources();         Bitmap bmp = BitmapFactory.decodeResource(res, bmpResId, opts);         if (bmp == null && isInEditMode()) {             // BitmapFactory.decodeResource doesn't work from the rendering             // library in Eclipse's Graphical Layout Editor. Use this workaround instead.             Drawable d = res.getDrawable(bmpResId);             int w = d.getIntrinsicWidth();             int h = d.getIntrinsicHeight();             bmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);             Canvas c = new Canvas(bmp);             d.setBounds(0, 0, w - 1, h - 1);             d.draw(c);         }         return bmp;     } } // //res\layout\lib_game.xml <?xml version="1.0" encoding="utf-8"?> <!--  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:gravity="center_horizontal"     >     <com.example.android.tictactoe.library.GameView         android:id="@+id/game_view"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_margin="20dip"         android:layout_weight="1"         />     <TextView         android:id="@+id/info_turn"         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:gravity="center_horizontal"         android:layout_marginBottom="10dip"         />     <Button         android:id="@+id/next_turn"         android:text="I'm done"         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:layout_marginLeft="20dip"         android:layout_marginRight="20dip"         /> </LinearLayout> // //res\layout-land\lib_game.xml <?xml version="1.0" encoding="utf-8"?> <!--  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="horizontal"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:gravity="center_vertical|center_horizontal"     >     <com.example.android.tictactoe.library.GameView         android:id="@+id/game_view"         android:layout_width="fill_parent"         android:layout_height="fill_parent"         android:layout_margin="20dip"         />     <LinearLayout         android:orientation="vertical"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:gravity="center_horizontal"         >         <TextView             android:id="@+id/info_turn"             android:layout_width="fill_parent"             android:layout_height="wrap_content"             android:gravity="center_horizontal"             android:layout_marginBottom="10dip"             />         <Button             android:id="@+id/next_turn"             android:text="I'm done"             android:minEms="10"             android:layout_width="fill_parent"             android:layout_height="wrap_content"             android:layout_marginLeft="20dip"             android:layout_marginRight="20dip"             />     </LinearLayout> </LinearLayout> // //res\values\strings.xml <?xml version="1.0" encoding="utf-8"?> <!--  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. --> <resources>     <string name="player2_win">Player 2 (computer) wins!</string>     <string name="player1_win">Player 1 (you) wins!</string>     <string name="tie">This is a tie! No one wins!</string>     <string name="player2_turn">Player 2\'s turn (that\'s the computer)</string>     <string name="player1_turn">Player 1\'s turn -- that\'s you!</string> </resources> // C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\TicTacToeMain\src\com\example\android\tictactoe\MainActivity.java /*  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package com.example.android.tictactoe; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import com.example.android.tictactoe.library.GameActivity; import com.example.android.tictactoe.library.GameView.State; public class MainActivity extends Activity {     /** Called when the activity is first created. */     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);         findViewById(R.id.start_player).setOnClickListener(                 new OnClickListener() {             public void onClick(View v) {                 startGame(true);             }         });         findViewById(R.id.start_comp).setOnClickListener(                 new OnClickListener() {             public void onClick(View v) {                 startGame(false);             }         });     }     private void startGame(boolean startWithHuman) {         Intent i = new Intent(this, GameActivity.class);         i.putExtra(GameActivity.EXTRA_START_PLAYER,                 startWithHuman ? State.PLAYER1.getValue() : State.PLAYER2.getValue());         startActivity(i);     } } // C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\TicTacToeMain\res\layout\main.xml <?xml version="1.0" encoding="utf-8"?> <!--  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:orientation="vertical"     android:layout_width="fill_parent"     android:layout_height="fill_parent"     android:gravity="center_horizontal"     >     <TextView         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:gravity="center_horizontal"         android:layout_marginTop="20dip"         android:layout_marginBottom="5dip"         android:text="@string/welcome"         />     <TextView         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:gravity="center_horizontal"         android:layout_marginBottom="5dip"         android:text="@string/explain2"         />     <TextView         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:gravity="center_horizontal"         android:layout_marginBottom="20dip"         android:text="@string/explain1"         />     <Button         android:id="@+id/start_player"         android:text="@string/start_player"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         />     <Button         android:id="@+id/start_comp"         android:text="@string/start_comp"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_marginBottom="10dip"         />     <ImageView         android:id="@+id/ImageView01"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:src="@drawable/icon"         /> </LinearLayout> // C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\TicTacToeMain\res\values\strings.xml <?xml version="1.0" encoding="utf-8"?> <!--  * Copyright (C) 2010 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License. --> <resources>     <string name="start_comp">Start -- Computer goes first</string>     <string name="start_player">Start -- Player goes first</string>     <string name="welcome"><b>Welcome to the Tic-Tac-Toe Sample!</b></string>     <string name="explain1">This sample code demonstrates how to split an application in multiple projects by using the \'project library\' available in the Froyo SDK Tools.</string>     <string name="explain2">This activity is defined in one project. The second activity, launched by one of the buttons below, is located in another project which is a \"library\" to the main one and merged in the same APK.</string>     <string name="app_name">Tic-Tac-Toe Sample</string> </resources>