java - 井字游戏,多人安卓

标签 java android bluetooth

我是 android 的新手,使用示例 api 使用蓝牙聊天代码创建了一个井字游戏,

我可以通过蓝牙连接两个设备并且可以使用蓝牙名称作为对手的名称

例如,如果我的设备名称是“ABC”而对手是“DEF” 那么我设备中的名称将是 You : 0 DEF: 0

opponets device will have names YOU : 0 ABC : 0
 ( the score is initially set to 0).

问题出在哪里:

这些设备中的每一个都将其视为玩家 1 并且可以进行移动。但我想限制它,首先尝试连接设备的玩家获得第一个 Action ,然后是另一个。

我该如何处理这种情况???请帮忙

我的代码:

public class test extends Activity {
// Debugging
private static final String TAG = "TicTacToe";
private static final boolean D = true;

// Message types sent from the BluetoothChatService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;

// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";

// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;

// Layout Views
private TextView mTitle;
private ListView mConversationView;
private EditText mOutEditText;
private Button mSendButton;

// Name of the connected device
private String mConnectedDeviceName = null;
// Array adapter for the conversation thread
private ArrayAdapter<String> mConversationArrayAdapter;
// String buffer for outgoing messages
private StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
// Member object for the chat services
private BluetoothGameService mGameService = null;
// Member object for the chat services
private BluetoothChatService mChatService = null;

//game variable

// player names initialized with default values.
CharSequence player_name_1 = "Player 1";
CharSequence player_name_2 = "Player 2";

// score initialized to 0.
public static int ben = 0;
int game_mode = 0;
int count = 0;              // to count the number of moves made.
int player = 1;             // sets the player no. to 1 by default.
int score_player_1 = 0;
int score_player_2 = 0;
int arr[][] = {{0,0,0},{0,0,0},{0,0,0}};    // array which stores the movements made.

// dialog IDs
 final int NAME_DIALOG_ID = 1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(D) Log.e(TAG, "+++ ON CREATE +++");

    // Set up the window layout
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.tictactoe);
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);

    // Set up the custom title
    mTitle = (TextView) findViewById(R.id.title_left_text);
    mTitle.setText(R.string.app_name);
    mTitle = (TextView) findViewById(R.id.title_right_text);

    // Get local Bluetooth adapter
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    // If the adapter is null, then Bluetooth is not supported
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
        finish();
        return;
    }     
    final Button st = (Button) findViewById(R.id.start); 
    st.setEnabled(false);
}

// set player names
protected Dialog onCreateDialog(int id){
    Dialog mdialog = new Dialog(this);
    switch(id) {
    case NAME_DIALOG_ID:
        mdialog.setContentView(R.layout.name);
        mdialog.setTitle("Player Names");
        mdialog.setCancelable(true);

        final EditText namep1 = (EditText) mdialog.findViewById(R.id.namep1);
        final EditText namep2 = (EditText) mdialog.findViewById(R.id.namep2);

        Button ok_b = (Button) mdialog.findViewById(R.id.ok);
        ok_b.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                player_name_2 = mConnectedDeviceName;   //player 2 name
                player_name_1 = "You";  //player 1 name
                score_player_1 = 0;
                score_player_2 = 0;
                new_game(namep1.getText());  //calling fn
                dismissDialog(1);
            }
        });
        break;
    default:
        mdialog = null;
    }
    return mdialog;
}

OnClickListener button_listener = new View.OnClickListener() {
    public void onClick(View v) {
        ImageButton ibutton = (ImageButton) v;

        // Button inactive for further clicks until a result is obtained.
        ibutton.setClickable(false);
        ibutton.setBackgroundResource(R.drawable.xo);
        // Increment Count on clicking the button.
        count++;

        if ((count % 2 != 0)) {
            player = 1;
            ibutton.setImageResource(R.drawable.system_cross);
        }
        else if ((count % 2 == 0)) {
            player = 2;         // human player.
            ibutton.setImageResource(R.drawable.system_dot);
        }
        // after_move function to check the result and decide.
        after_move(ibutton);
    }
};    

public void new_game(CharSequence player_name) {

    setContentView(R.layout.tictactoe);

    final ImageButton b3 = (ImageButton) findViewById(R.id.b3);
    final ImageButton b2 = (ImageButton) findViewById(R.id.b2);
    final ImageButton b1 = (ImageButton) findViewById(R.id.b1);

    final ImageButton b6 = (ImageButton) findViewById(R.id.b6);
    final ImageButton b5 = (ImageButton) findViewById(R.id.b5);
    final ImageButton b4 = (ImageButton) findViewById(R.id.b4);

    final ImageButton b9 = (ImageButton) findViewById(R.id.b9);
    final ImageButton b8 = (ImageButton) findViewById(R.id.b8);
    final ImageButton b7 = (ImageButton) findViewById(R.id.b7);

    // set the OnClickListeners.
    b1.setOnClickListener(button_listener);
    b2.setOnClickListener(button_listener);
    b3.setOnClickListener(button_listener);
    b4.setOnClickListener(button_listener);
    b5.setOnClickListener(button_listener);
    b6.setOnClickListener(button_listener);
    b7.setOnClickListener(button_listener);
    b8.setOnClickListener(button_listener);
    b9.setOnClickListener(button_listener);

    // Re-enable the Click-able property of buttons.
    b1.setClickable(true);
    b2.setClickable(true);
    b3.setClickable(true);
    b4.setClickable(true);
    b5.setClickable(true);
    b6.setClickable(true);
    b7.setClickable(true);
    b8.setClickable(true);
    b9.setClickable(true);

    // dismissDialog(NAME_DIALOG_ID);
    // dismissDialog(HELP_DIALOG_ID);


    // update the score board with the already existing values.
    // this line should come ONLY after the player name is set in the above lines.
    set_score(3);   

     // reset the array arr.
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            arr[i][j] = 0; 

    /* *********************************************************
     * Initiates the computer's chance during start of the game,
     * as well as when there is a win / loose and the next
     * chance is for the computer.
     * ********************************************************* 
    if ((game_mode == 1) && (count % 2 != 0))
        CompGame();
        */
}

public void set_score(int player_number) {
    TextView tv = (TextView) findViewById(R.id.scoreboard);

    if (player_number == 1)
        score_player_1 += 1;
    else if (player_number == 2)
        score_player_2 += 1;
    else ;                          // Don't change score, but set the score board right.

    CharSequence score_txt = player_name_1 + "  :  " + score_player_1 + "                   " + player_name_2 + "  :  " + score_player_2;
    tv.setText(score_txt);
}

public void after_move (ImageButton ib) {
    CharSequence pos_str = "";              // position as a string.
    int pos = 0;
    boolean result = false;

    pos_str = (CharSequence) ib.getTag();   // get the position from the tag.
    pos = (int) pos_str.charAt(0) - 48;     // char to integer conversion.

    // set the values in the array according to the player number.
    if (player == 1) {
        if (pos < 4)                
            arr[0][pos - 1] = 1;
        else if (pos < 7) 
            arr[1][(pos - 1) % 3] = 1;
        else if (pos < 10)
            arr[2][(pos - 1) % 3] = 1;
    }
    else {
        if (pos < 4)                
            arr[0][pos - 1] = 2;
        else if (pos < 7) 
            arr[1][(pos - 1) % 3] = 2;
        else if (pos < 10)
            arr[2][(pos - 1) % 3] = 2;
    }

    // Check for the game result.
    result = result_check(player);

    // Result check section.
    if (result == true) {
        //  check for the player number.
        if (player == 1) {
            set_score(1);
            if (game_mode == 0) {
                show_result("Congrats. " + player_name_1 + " wins !!");
            }
        }
        else {
            set_score(2);
            if (game_mode == 0) {   // human vs human  
                show_result("Congrats. " + player_name_2 + " wins !!");
            }
        }
        return;
    }
    else if ((result == false) && arr_isFull()) {
        show_result("    Game Draw !    ");             // leave the space, or else dialog becomes cramped.
        return;
    }
    else { } // continue game.
}

public boolean result_check(int player_local) {
    boolean win = true;
    int k = 0;

    // check for horizontal condition only.
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (arr[i][j] != player_local) {        // check with player number.
                win = false;
                break;
            }
        } // column loop.
        if (win == true) {
            return true;
        }
        win = true;
    } // row loop.

    win = true;         // resetting win to true.

    // checking for vertical condition only.
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (arr[j][i] != player_local) {
                win = false;
                break;
            }
        } // column loop.
        if (win == true) {
            return true;
        }
        win = true;
    } // row loop.

    win = true;         // reset win to true.

    // check for diagonal condition 1.
    for (int i = 0; i < 3; i++)
        if (arr[i][k++] != player_local) {
            win = false;
            break;
        }

    if (win == true) {
        return true;
    }

    k = 2;
    win = true;         // reset win to true;

    // check for diagonal condition 2.
    for (int i = 0; i < 3; i++)
        if (arr[i][k--] != player_local) {
            win = false;
            break;
        }

    if (win == true) {
        return true;
    }

    return false;
}

public boolean show_result(CharSequence message)        //function to select the game mode
{   
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(message)
                .setPositiveButton("Continue", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        // reset the game environment.
                            new_game(player_name_2);
                    }
                });
    AlertDialog alert = builder.create();
    alert.show();
    return true;
}

public boolean arr_isFull () {
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (arr[i][j] == 0)
                return false;               
    return true;
}


@Override
public void onStart() {
    super.onStart();
    if(D) Log.e(TAG, "++ ON START ++");

    // If BT is not on, request that it be enabled.
    // setupChat() will then be called during onActivityResult
    if (!mBluetoothAdapter.isEnabled()) {
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    // Otherwise, setup the chat session
    } else {
        if (mGameService == null)
            setupGame();
    }
}

private void setupGame() {
    Log.d(TAG, "setupGame()");

    // Initialize the BluetoothGameService to perform bluetooth connections
    mGameService = new BluetoothGameService(this, mHandler);

    // Initialize the buffer for outgoing messages
    mOutStringBuffer = new StringBuffer("");
}

@Override
public synchronized void onResume() {
    super.onResume();
    if(D) Log.e(TAG, "+ ON RESUME +");

    // Performing this check in onResume() covers the case in which BT was
    // not enabled during onStart(), so we were paused to enable it...
    // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
    if (mGameService != null) {
        // Only if the state is STATE_NONE, do we know that we haven't started already
        if (mGameService.getState() == BluetoothChatService.STATE_NONE) {
          // Start the Bluetooth chat services
          mGameService.start();
        }
    }
}

@Override
public synchronized void onPause() {
    super.onPause();
    if(D) Log.e(TAG, "- ON PAUSE -");
}

@Override
public void onStop() {
    super.onStop();
    if(D) Log.e(TAG, "-- ON STOP --");
}

@Override
public void onDestroy() {
    super.onDestroy();
    // Stop the Bluetooth chat services
    if (mGameService != null) mGameService.stop();
    if(D) Log.e(TAG, "--- ON DESTROY ---");
}

/**
 * Sends a message.
 * @param message  A string of text to send.
 */

private void sendMessage(String message) {
    // Check that we're actually connected before trying anything
    if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
        Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
        return;
    }

    // Check that there's actually something to send
    if (message.length() > 0) {
        // Get the message bytes and tell the BluetoothChatService to write
        byte[] send = message.getBytes();
        mChatService.write(send);
        // Reset out string buffer to zero and clear the edit text field
        mOutStringBuffer.setLength(0);
        mOutEditText.setText(mOutStringBuffer);
    }
}

//从 BluetoothChatService 获取信息的 Handler

    private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothGameService.STATE_CONNECTED:
                mTitle.setText(R.string.title_connected_to);
                mTitle.append(mConnectedDeviceName);
                //mConversationArrayAdapter.clear();
                break;
            case BluetoothGameService.STATE_CONNECTING:
                mTitle.setText(R.string.title_connecting);
                break;
            case BluetoothGameService.STATE_LISTEN:
            case BluetoothGameService.STATE_NONE:
                mTitle.setText(R.string.title_not_connected);
                break;
            }
            break;
        case MESSAGE_WRITE:
            byte[] writeBuf = (byte[]) msg.obj;
            // construct a string from the buffer
            String writeMessage = new String(writeBuf);
            //mConversationArrayAdapter.add("Me:  " + writeMessage);
            break;
        case MESSAGE_READ:
            byte[] readBuf = (byte[]) msg.obj;
            // construct a string from the valid bytes in the buffer
            String readMessage = new String(readBuf, 0, msg.arg1);
            //mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);
            break;
        case MESSAGE_DEVICE_NAME:
            // save the connected device's name
            mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
            Toast.makeText(getApplicationContext(), "Connected to "
                           + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
            if(ben>0)
            {
                final Button st = (Button) findViewById(R.id.start); // enable start button
                st.setEnabled(true);
            }
            else
            {
                final Button st = (Button) findViewById(R.id.start); // disable start button
                st.setEnabled(false);
            }
            break;
        case MESSAGE_TOAST:
            Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                           Toast.LENGTH_SHORT).show();
            break;
        }
    }
};

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(D) Log.d(TAG, "onActivityResult " + resultCode);
    switch (requestCode) {
    case REQUEST_CONNECT_DEVICE:
        // When DeviceListActivity returns with a device to connect
        if (resultCode == Activity.RESULT_OK) {
            // Get the device MAC address
            String address = data.getExtras()
                                 .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
            // Get the BLuetoothDevice object
            BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
            // Attempt to connect to the device
            mGameService.connect(device);
        }
        break;
    case REQUEST_ENABLE_BT:
        // When the request to enable Bluetooth returns
        if (resultCode == Activity.RESULT_OK) {
            // Bluetooth is now enabled, so set up a chat session
            setupGame();
        } else {
            // User did not enable Bluetooth or an error occured
            Log.d(TAG, "BT not enabled");
            Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
            finish();
        }
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.activity_main, menu);
    return true;
}

private void ensureDiscoverable() {
    if(D) Log.d(TAG, "ensure discoverable");
    if (mBluetoothAdapter.getScanMode() !=
        BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
        Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
        startActivity(discoverableIntent);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.scan:
        ben = ben + 1;
        // Launch the DeviceListActivity to see devices and do scan
        Intent serverIntent = new Intent(this, DeviceListActivity.class);
        startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
        return true;
    case R.id.discoverable:
        // Ensure this device is discoverable by others
        ensureDiscoverable();
        return true;
    }
    return false;
}

//when start is pressed
public void start(View v){
    //showDialog(NAME_DIALOG_ID);
    player_name_2 = mConnectedDeviceName;   //player 2 name
    player_name_1 = "You";  //player 1 name
    score_player_1 = 0;
    score_player_2 = 0;
    new_game(player_name_1);  //calling fn
}

//when back | return button is pressed

public void back(View v){
    player_name_1 = "Player 1";
    player_name_2 = "Player 2";

    count = 0;              
    player = 1;             
    score_player_1 = 0;
    score_player_2 = 0;

    Intent open = new Intent("com.example.tictactoechat_abs.STARTINGPOINT");
    startActivity(open); 
}

}

最佳答案

我建议在建立连接后,在游戏开始之前,您在客户端上发送一条消息,说“游戏开始了,我先走了”。如果一个人按“加入”而另一个人按“主持人”,您大概可以分辨出谁尝试连接。

或者,您可以通过让双方发送一个随机数来随机化它,谁是最高的先行。

关于java - 井字游戏,多人安卓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18537120/

相关文章:

java - 如何使用 HttpURLConnection 将序列化对象从 Java 类发送到 Servlet?

java - Java中任意两种基本类型之间的转换

java - 从 Oracle 数据库中检索日期列时如何忽略 java 所做的 DST 调整?

Android 在 wifi direct 和非 wifi direct 设备之间传输数据

android - 如何让 Android 5.0+ 上的蓝牙 HID 主机正常工作

java - java中的模式/数组问题

android - 计算耗时(第二个时间标记 - 第一个时间标记)

android - 带有 MathJax 的 ListView 中的 WebViews

linux - 使用 hciattach 通过 uart 蓝牙?

c# - 通用Windows应用程序蓝牙支持