1

我是 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 并且可以移动。但我想限制它,首先尝试连接设备的玩家获得第一手,然后是另一手。

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

我的代码:

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); 
}

}
4

2 回答 2

1

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

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

于 2013-08-30T16:08:31.737 回答
0

您可以创建一个代表玩家的玩家类。在那里,您可以将实例变量设置为所需的数字,每次将其递增一。然后,编号最小的玩家可以先走,其余玩家按照该编号的顺序紧随其后。然后,您可以拥有一个类来管理所有播放器对象。该类将负责检查下一个可用号码并将其分配给玩家。

于 2013-08-30T16:31:49.467 回答