当前位置: 首页 > 知识库问答 >
问题:

如何为tic tac toe游戏创建简单、中等和困难的关卡?

鲁乐
2023-03-14

目前我正在用android开发tic-tac-toe游戏

我成功创建了游戏,但面临一些问题

这是我迄今为止尝试过的代码

这里是我的木板视图

public class BoardView extends View implements GestureDetector.OnGestureListener, ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
    private static final int STROKE_WIDTH = 10;
    private static final int SWEEPER_WIDTH = 20;

    private float[] gridLinePoints;
    private Paint gridPaint;

    private PointF[][] centerPoints;
    private Paint signPaint;

    private List<SignData> signDataList;

    private @Constants.WinLinePosition int winLinePosition;
    private Paint winLinePaint;

    private GestureDetector clickDetector;
    private OnBoardInteractionListener onBoardInteractionListener;

    private ValueAnimator clickAnimator;
    private ValueAnimator winLineAnimator;
    private ValueAnimator resetAnimator;

    private float signRadius;
    private float winLineLength;
    private float sweeperStartPosition;

    private Paint sweeperPaint;
    private int[] sweeperColors;
    private float[] sweeperStops;

    public BoardView(Context context) {
        super(context);
        init();
    }

    public BoardView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public BoardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @TargetApi(Build.VERSION_CODES.M)
    private void init() {
        gridLinePoints = new float[16];

        centerPoints = new PointF[3][3];
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                centerPoints[i][j] = new PointF();
            }
        }

        signDataList = new ArrayList<>();

        winLinePosition = Constants.NONE;

        gridPaint = new Paint();
        gridPaint.setColor(getContext().getResources().getColor(R.color.holo_green_dark, null));
        gridPaint.setAntiAlias(true);
        gridPaint.setStrokeWidth(dpToPx(STROKE_WIDTH));
        gridPaint.setStrokeCap(Paint.Cap.ROUND);

        signPaint = new Paint();
        signPaint.setColor(getContext().getResources().getColor(R.color.holo_orange_dark, null));
        signPaint.setAntiAlias(true);
        signPaint.setStyle(Paint.Style.STROKE);
        signPaint.setStrokeWidth(dpToPx(STROKE_WIDTH));
        signPaint.setStrokeCap(Paint.Cap.ROUND);

        winLinePaint = new Paint();
        winLinePaint.setColor(getContext().getResources().getColor(R.color.holo_red_dark, null));
        winLinePaint.setAntiAlias(true);
        winLinePaint.setStrokeWidth(dpToPx(STROKE_WIDTH));
        winLinePaint.setStrokeCap(Paint.Cap.ROUND);

        clickDetector = new GestureDetector(getContext(), this);

        clickAnimator = new ValueAnimator();
        clickAnimator.setDuration(150);
        clickAnimator.setInterpolator(new DecelerateInterpolator());
        clickAnimator.addUpdateListener(this);
        clickAnimator.addListener(this);

        winLineAnimator = new ValueAnimator();
        winLineAnimator.setDuration(150);
        winLineAnimator.setInterpolator(new DecelerateInterpolator());
        winLineAnimator.addUpdateListener(this);
        winLineAnimator.addListener(this);

        resetAnimator = new ValueAnimator();
        resetAnimator.setDuration(500);
        resetAnimator.setInterpolator(new AccelerateInterpolator());
        resetAnimator.addUpdateListener(this);
        resetAnimator.addListener(this);

        sweeperPaint = new Paint();
        sweeperPaint.setAntiAlias(true);
        sweeperPaint.setStyle(Paint.Style.FILL);

        sweeperColors = new int[3];
        sweeperColors[0] = Color.parseColor("#0000DDFF");
        sweeperColors[1] = Color.parseColor("#FF00DDFF");
        sweeperColors[2] = Color.parseColor("#0000DDFF");

        sweeperStops = new float[3];
        sweeperStops[0] = 0;
        sweeperStops[1] = 0.5f;
        sweeperStops[2] = 1;

        setLayerType(LAYER_TYPE_SOFTWARE, sweeperPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        getLayoutParams().height = getMeasuredWidth();

        setGridLinePoints();
        setCenterPoints();
        setAnimationValues();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawGrid(canvas);
        super.onDraw(canvas);

        if (resetAnimator.isRunning()) {
            canvas.clipRect(0, sweeperStartPosition, getMeasuredWidth(), getMeasuredWidth());

            setSweeperGradient();
            canvas.drawRect(0, sweeperStartPosition, getMeasuredWidth(), sweeperStartPosition + dpToPx(SWEEPER_WIDTH), sweeperPaint);
        }

        drawSigns(canvas);
        drawWinLine(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if ((!isEnabled()) || (clickAnimator.isRunning()) || (isAnimationFlagSet())) {
            return super.onTouchEvent(event);
        } else {
            return clickDetector.onTouchEvent(event);
        }
    }

    private boolean isAnimationFlagSet() {
        for (SignData signData : signDataList) {
            if (signData.isAnimationFlag()) {
                return true;
            }
        }
        return false;
    }

    private void setGridLinePoints() {
        int side = getMeasuredWidth();
        float padding = dpToPx(STROKE_WIDTH / 2f);

        gridLinePoints[0] = gridLinePoints[4] = gridLinePoints[9] = gridLinePoints[13] = padding;
        gridLinePoints[1] = gridLinePoints[3] = gridLinePoints[8] = gridLinePoints[10] = side / 3f;
        gridLinePoints[2] = gridLinePoints[6] = gridLinePoints[11] = gridLinePoints[15] = side - padding;
        gridLinePoints[5] = gridLinePoints[7] = gridLinePoints[12] = gridLinePoints[14] = (2 * side) / 3f;
    }

    private void setCenterPoints() {
        float a = getMeasuredWidth() / 6f;

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                centerPoints[i][j].x = a + (j * (2 * a));
                centerPoints[i][j].y = a + (i * (2 * a));
            }
        }
    }

    private void setAnimationValues() {
        clickAnimator.setFloatValues(0, (getMeasuredWidth() / 6f) - dpToPx(2 * STROKE_WIDTH));
        winLineAnimator.setFloatValues(0, getMeasuredWidth());
        resetAnimator.setFloatValues(-dpToPx(SWEEPER_WIDTH), getMeasuredWidth());
    }

    private void setSweeperGradient() {
        float axis = sweeperStartPosition + (dpToPx(SWEEPER_WIDTH / 2f));

        LinearGradient horizontalGradient = new LinearGradient(0, axis, getMeasuredWidth(), axis,
                sweeperColors, sweeperStops, Shader.TileMode.CLAMP);

        LinearGradient verticalGradient = new LinearGradient(getMeasuredWidth() / 2f, sweeperStartPosition,
                getMeasuredWidth() / 2f, sweeperStartPosition + dpToPx(SWEEPER_WIDTH), sweeperColors, sweeperStops,
                Shader.TileMode.CLAMP);

        ComposeShader shader = new ComposeShader(horizontalGradient, verticalGradient, PorterDuff.Mode.MULTIPLY);

        sweeperPaint.setShader(shader);
    }

    private void drawGrid(Canvas canvas) {
        canvas.drawLines(gridLinePoints, gridPaint);
    }

    private void drawSigns(Canvas canvas) {
        for (int i = 0; i < signDataList.size(); i++) {
            SignData signData = signDataList.get(i);

            switch (signData.getSign()) {
                case Constants.CIRCLE:
                    drawCircle(canvas, centerPoints[signData.getRow()][signData.getColumn()], signData.isAnimationFlag());
                    break;
                case Constants.CROSS:
                    drawCross(canvas, centerPoints[signData.getRow()][signData.getColumn()], signData.isAnimationFlag());
                    break;
                case Constants.EMPTY:
                    break;
            }
        }
    }

    private void drawCircle(Canvas canvas, PointF center, boolean animationFlag) {
        float radius = animationFlag ? signRadius : (getMeasuredWidth() / 6f) - dpToPx(2 * STROKE_WIDTH);

        canvas.drawCircle(center.x, center.y, radius, signPaint);
    }

    private void drawCross(Canvas canvas, PointF center, boolean animationFlag) {
        float radius = animationFlag ? signRadius : (getMeasuredWidth() / 6f) - dpToPx(2 * STROKE_WIDTH);

        canvas.drawLine(center.x - radius, center.y - radius, center.x + radius, center.y + radius, signPaint);
        canvas.drawLine(center.x - radius, center.y + radius, center.x + radius, center.y - radius, signPaint);
    }

    private void drawWinLine(Canvas canvas) {
        float length = winLineLength;

        float a = getMeasuredWidth() / 6f;

        float padding = dpToPx(STROKE_WIDTH);

        switch (winLinePosition) {
            case Constants.NONE:
                break;
            case Constants.ROW_1:
                canvas.drawLine(padding, a, length - padding, a, winLinePaint);
                break;
            case Constants.ROW_2:
                canvas.drawLine(padding, a + (2 * a), length - padding, a + (2 * a), winLinePaint);
                break;
            case Constants.ROW_3:
                canvas.drawLine(padding, a + (4 * a), length - padding, a + (4 * a), winLinePaint);
                break;
            case Constants.COLUMN_1:
                canvas.drawLine(a, padding, a, length - padding, winLinePaint);
                break;
            case Constants.COLUMN_2:
                canvas.drawLine(a + (2 * a), padding, a + (2 * a), length - padding, winLinePaint);
                break;
            case Constants.COLUMN_3:
                canvas.drawLine(a + (4 * a), padding, a + (4 * a), length - padding, winLinePaint);
                break;
            case Constants.DIAGONAL_1:
                canvas.drawLine(padding, padding, length - padding, length - padding, winLinePaint);
                break;
            case Constants.DIAGONAL_2:
                canvas.drawLine(getMeasuredWidth() - padding, padding, padding + getMeasuredWidth()
                        - length, length - padding, winLinePaint);
                break;
        }
    }

    void addSignToBoard(@Constants.Sign int sign, int row, int column) {
        SignData signData = new SignData();
        signData.setSign(sign);
        signData.setRow(row);
        signData.setColumn(column);
        signData.setAnimationFlag(true);

        if (clickAnimator.isRunning()) {
            clickAnimator.end();
        }

        signDataList.add(signData);
        clickAnimator.start();
    }

    void showWinLine(@Constants.WinLinePosition int winLinePosition) {
        this.winLinePosition = winLinePosition;

        winLineAnimator.start();
    }

    void resetBoard() {
        if (!resetAnimator.isRunning()) {
            resetAnimator.start();
        }
    }

    boolean isAlreadyAdded(int row, int column) {
        for (int i = 0; i < signDataList.size(); i++) {
            SignData signData = signDataList.get(i);

            if ((signData.getRow() == row) && (signData.getColumn() == column)) {
                return true;
            }
        }

        return false;
    }

    private float dpToPx(float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics());
    }

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        float x = e.getX();
        float y = e.getY();

        int row = detectIndexOfPartition(y);
        int column = detectIndexOfPartition(x);

        if ((row != -1) && (column != -1)) {
            onBoardInteractionListener.onBoardClick(BoardView.this, row, column);
        }

        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }

    private int detectIndexOfPartition(float value) {
        float maxValue = getMeasuredWidth();
        float totalNumberOfPartitions = 3;

        float lengthOfSinglePartition = maxValue / totalNumberOfPartitions;

        return (int) (value / lengthOfSinglePartition);
    }

    public void setOnBoardInteractionListener(OnBoardInteractionListener onBoardInteractionListener) {
        this.onBoardInteractionListener = onBoardInteractionListener;
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        if (animation == clickAnimator) {
            signRadius = (float) animation.getAnimatedValue();
        } else if (animation == winLineAnimator) {
            winLineLength = (float) animation.getAnimatedValue();
        } else if (animation == resetAnimator) {
            sweeperStartPosition = (float) animation.getAnimatedValue();
        }
        invalidate();
    }

    @Override
    public void onAnimationStart(Animator animation) {

    }

    @Override
    public void onAnimationEnd(Animator animation) {
        if (animation == clickAnimator) {
            SignData signData = signDataList.get(signDataList.size() - 1);
            signData.setAnimationFlag(false);
            onBoardInteractionListener.onSignAdded(signData.getSign(), signData.getRow(), signData.getColumn());
            signRadius = 0;
        } else if (animation == resetAnimator) {
            signDataList.clear();
            winLinePosition = Constants.NONE;
            onBoardInteractionListener.onBoardReset();
        }
    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }

    interface OnBoardInteractionListener {

        void onBoardClick(BoardView board, int row, int column);

        void onSignAdded(@Constants.Sign int sign, int row, int column);

        void onBoardReset();
    }

    private class SignData {
        private @Constants.Sign int sign;
        private int row;
        private int column;
        private boolean animationFlag;

        @Constants.Sign int getSign() {
            return sign;
        }

        void setSign(@Constants.Sign int sign) {
            this.sign = sign;
        }

        int getRow() {
            return row;
        }

        void setRow(int row) {
            this.row = row;
        }

        int getColumn() {
            return column;
        }

        void setColumn(int column) {
            this.column = column;
        }

        boolean isAnimationFlag() {
            return animationFlag;
        }

        void setAnimationFlag(boolean animationFlag) {
            this.animationFlag = animationFlag;
        }
    }
}

我的大脑课

class Brain {
    private static Brain INSTANCE;

    private @Constants.Sign
    int[][] board = new int[3][3];

    private int rowOfResult;
    private int columnOfResult;

    private int depth;

    private @Constants.Sign
    int computerSign;
    private @Constants.Sign
    int playerSign;

    private OnProcessCompleteListener onProcessCompleteListener;

    private static final int HORIZONTAL = 0;
    private static final int VERTICAL = 1;
    private static final int DIAGONAL = 2;

    @IntDef({HORIZONTAL, VERTICAL, DIAGONAL})
    @interface DirectionOfWinLine {

    }

    // References used by isWin function.
    private int[] winSequence = new int[3];
    private int[] row = new int[3];
    private int[] column = new int[3];
    private int[] diagonal1 = new int[3];
    private int[] diagonal2 = new int[3];

    private Brain() {
    }

    static Brain getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Brain();
        }
        return INSTANCE;
    }

    void play() {
        if (onProcessCompleteListener == null) {
            return;
        }
        calculateNextMove(computerSign, depth);

        onProcessCompleteListener.onNextMoveCalculated(rowOfResult, columnOfResult);
    }

    private int calculateNextMove(@Constants.Sign int sign, int depth) {

        if (isWin(computerSign, false)) {
            return 10 - depth;
        } else if (isWin(playerSign, false)) {
            return depth - 10;
        }

        if (depth >= 9) {
            return 0;
        }

        List<Integer> scores = new ArrayList<>(), rowIndices = new ArrayList<>(), columnIndices = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == Constants.EMPTY) {
                    board[i][j] = sign;
                    scores.add(calculateNextMove(getOppositeSign(sign), depth + 1));
                    rowIndices.add(i);
                    columnIndices.add(j);
                    board[i][j] = Constants.EMPTY;
                }
            }
        }

        if (sign == computerSign) {
            int maxScore = -100;
            for (int i = 0; i < scores.size(); i++) {
                if (scores.get(i) > maxScore) {
                    maxScore = scores.get(i);
                }
            }
            return randomizeScore(maxScore, scores, rowIndices, columnIndices);

        } else {
            int minScore = 100;
            for (int i = 0; i < scores.size(); i++) {
                if (scores.get(i) < minScore) {
                    minScore = scores.get(i);
                }
            }
            return randomizeScore(minScore, scores, rowIndices, columnIndices);
        }
    }

    private int randomizeScore(int score, List<Integer> scores, List<Integer> rowIndices, List<Integer> columnIndices) {
        List<Integer> equalScoreIndices = new ArrayList<>();

        for (int i = 0; i < scores.size(); i++) {
            if (scores.get(i) == score) {
                equalScoreIndices.add(i);
            }
        }

        Random rand = new Random();
        int randomIndex = equalScoreIndices.get(rand.nextInt(equalScoreIndices.size()));

        rowOfResult = rowIndices.get(randomIndex);
        columnOfResult = columnIndices.get(randomIndex);

        return score;
    }

    private boolean isWin(@Constants.Sign int sign, boolean notifyWinEnabled) {
        for (int i = 0; i < 3; i++) {
            winSequence[i] = sign;
        }

        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {

                if (i == j) {
                    diagonal1[i] = board[i][j];
                }
                if ((i + j) == 2) {
                    diagonal2[i] = board[i][j];
                }

                row[j] = board[i][j];
                column[j] = board[j][i];
            }

            if (isEqual(row, winSequence)) {
                if (notifyWinEnabled) {
                    notifyWin(sign, HORIZONTAL, i + 1);
                }
                return true;
            } else if (isEqual(column, winSequence)) {
                if (notifyWinEnabled) {
                    notifyWin(sign, VERTICAL, i + 1);
                }
                return true;
            }
        }

        if (isEqual(diagonal1, winSequence)) {
            if (notifyWinEnabled) {
                notifyWin(sign, DIAGONAL, 1);
            }
            return true;
        } else if (isEqual(diagonal2, winSequence)) {
            if (notifyWinEnabled) {
                notifyWin(sign, DIAGONAL, 2);
            }
            return true;
        }

        return false;
    }

    private boolean isEqual(int[] x, int[] y) {
        for (int i = 0; i < 3; i++) {
            if (x[i] != y[i]) {
                return false;
            }
        }
        return true;
    }

    void analyzeBoard() {
        if (onProcessCompleteListener == null) {
            return;
        }

        if ((!isWin(Constants.CIRCLE, true)) && (!isWin(Constants.CROSS, true)) && (depth >= 9)) {
            onProcessCompleteListener.onGameDraw();
        }
    }

    private void notifyWin(@Constants.Sign int sign, @DirectionOfWinLine int direction, int index) {
        if (onProcessCompleteListener == null) {
            return;
        }

        @Constants.WinLinePosition int winLinePosition = Constants.NONE;

        switch (direction) {
            case HORIZONTAL:
                switch (index) {
                    case 1:
                        winLinePosition = Constants.ROW_1;
                        break;
                    case 2:
                        winLinePosition = Constants.ROW_2;
                        break;
                    case 3:
                        winLinePosition = Constants.ROW_3;
                        break;
                }
                break;
            case VERTICAL:
                switch (index) {
                    case 1:
                        winLinePosition = Constants.COLUMN_1;
                        break;
                    case 2:
                        winLinePosition = Constants.COLUMN_2;
                        break;
                    case 3:
                        winLinePosition = Constants.COLUMN_3;
                        break;
                }
                break;
            case DIAGONAL:
                switch (index) {
                    case 1:
                        winLinePosition = Constants.DIAGONAL_1;
                        break;
                    case 2:
                        winLinePosition = Constants.DIAGONAL_2;
                        break;
                }
                break;
        }

        onProcessCompleteListener.onGameWin(sign, winLinePosition);
    }

    void reset() {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                board[i][j] = Constants.EMPTY;
            }
        }
        depth = 0;
    }

    void setComputerSign(int computerSign) {
        this.computerSign = computerSign;
        playerSign = getOppositeSign(computerSign);
    }

    void updateBoard(@Constants.Sign int sign, int row, int column) {
        board[row][column] = sign;
        depth++;
    }

    private @Constants.Sign
    int getOppositeSign(@Constants.Sign int sign) {
        return sign == Constants.CIRCLE ? Constants.CROSS : Constants.CIRCLE;
    }

    void setOnProcessCompleteListener(OnProcessCompleteListener onProcessCompleteListener) {
        this.onProcessCompleteListener = onProcessCompleteListener;
    }

    interface OnProcessCompleteListener {

        void onNextMoveCalculated(int row, int column);

        void onGameWin(@Constants.Sign int sign, @Constants.WinLinePosition int winLinePosition);

        void onGameDraw();
    }

    void destroy() {
        INSTANCE = null;
    }
}

我已经为此创建了github repo,这里提供了所有代码

https://github.com/SuperSaiyanGoku3/MyGame

我在上面的代码中遇到了一些问题

  1. 上面的代码只支持硬级别(不可能),我怎样才能在上面的游戏算法中再创建简单的中硬级别计算机(CPU)

以下是一些我到目前为止尝试过的链接,但无法理解如何创建简单、中等和硬级别

  • 学习为Android创建Tic-Tac-Toe游戏
  • Android Studio-JAVA-TIC-TAC-TOE
  • Android tic tac-toe游戏-逻辑问题
  • Tic Tac Toe(桌面布局)Android应用程序
  • 井字游戏

如果需要更多信息,请让我知道。提前感谢。你的努力将受到赞赏。

共有3个答案

白子明
2023-03-14

用“n x n矩阵”完成Tic Tac Toe

基本思想是,我们只需要检查列/行/对角线元素是否相同。用C#编写的代码,带有基本单元测试。

公孙志
2023-03-14

如果你使用minimax策略玩tic-tac-toe,你可以有多个切换案例,对应游戏中不同的难度等级。最简单的方法是在minimax树中设置不同的深度阈值。例如,您可以将minimax游戏树扩展到仅深度2(假设为3*3 tic tac toe)以获得简单级别,也可以说直到搜索树结束以获得最高难度级别。您可以根据电路板大小和预期难度设置此阈值。

实现难度级别的另一种方法是通过实现不同的启发式函数来计算棋盘得分(对棋盘当前状态的一种良好度量)。您可以使用启发式函数,根据您在该行/列/对角线中占据的单元格数量来评估单个行/列/对角线分数。例如,如果占用的单元格数为1,则score=x(x可以是任意数)。如果占用的单元格数为2,则得分=x^2,如果为3,则得分=x^3。然后乘以所有各条线的分数,得到每一行、每一列或每一对角线上的善良程度(或者你可以将其视为获胜概率)。你可以为你的对手计算一个类似的分数,然后取一个差值来获得棋盘分数。因此,我们的想法是通过为每个难度级别设计不同的启发式函数来实现评估当前电路板状态的不同方法。一个糟糕的启发式函数可以作为一个简单的级别,因为它会输掉很多游戏,而一个设计合理的启发式函数则会有一个不输的策略(它最终会赢得或平局)。

为了在游戏的每次运行中随机选择一个难度级别,您可以使用随机数生成器来选择一个难度级别。您可以将'0'指定为简单,'1'指定为中等,'2'指定为硬。您可以使用以下java函数生成0和(n-1)之间的整数

int random=random。nextInt(n)

魏成济
2023-03-14

>

  • 实现难度:对于支持简单和中等难度,我建议你只使用随机。你已经实现了困难,所以你只需要犯“错误”的难度较小的逻辑,这个错误可以随机实现。

    private void calculateNextMoveRandom() {
        Random rand = new Random();
    
        int randomRow;
        int randomColumn;
    
        while (true) {
            randomRow = rand.nextInt(3);
            randomColumn = rand.nextInt(3);
    
            if (Constants.EMPTY == board[randomRow][randomColumn]) {
                rowOfResult = randomRow;
                columnOfResult = randomColumn;
                return;
            }
        }
    }
    


    2.位图标记:您可以使用BitmapFactory.decode资源()在屏幕上绘制位图。

        private void drawCircle(Canvas canvas, PointF center, boolean animationFlag) {
            int iconSize = (int) LayoutUtil.getPixelFromDp(MARKER_SIZE, getContext());
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android);
            Bitmap scaled = Bitmap.createScaledBitmap(bitmap, iconSize, iconSize, true);
            canvas.drawBitmap(scaled, center.x - (iconSize >> 1), center.y - (iconSize >> 1), signPaint);
        }
    


    三,。随机难度:只需使用随机设置难度。

        brain.setDifficulty(new Random().nextInt(3));
    

    这是我的请求:
    https://github.com/SuperSaiyanGoku3/MyGame/pull/1

  •  类似资料:
    • 我是Java的初学者,所以我不太懂。我在大学的课程中学习Java,我正在为作业做骰子游戏。

    • 我是一个仍在学习Android系统的开发人员,到目前为止,我已经创建了两个应用程序,一个闹钟,一个小部件和一个使用数据库的通行证管理器,我有一点经验,但我想创建一个2D侧滚动游戏,我在网上查看,有不同的教程,但是,开始使用它的最佳方法是什么?我读过libgdx,但我不确定它是否过时。 我看到所有的游戏都是用Java制作的,然后移植到Android系统,这是正确的吗?我希望得到一些指导,谢谢!

    • 我在做一个2D跑步者游戏,我用它做了框架 每次我创建一个类时,我每次都是这样制作JFrames,没有重新调用这个类或其他任何东西。我用连接到其他类的按钮完成了菜单,但我现在需要做一个关卡。它包括一个玩家左右向上移动,与平台和敌人发生碰撞。有点像超级马里奥。我是Java的初学者,所以我还没有找到任何遵循我的结构的示例,因为它们都基于JFrame 1。我不知道如何制作互动程序并将其连接到类的JFram

    • 我很难把我的心思放在这件事上。每当玩家猜错时,它应该从最初的余额中减去他/她的赌注。由于它是在一个循环中,它总是从一开始就取初始平衡,每次都吐出相同的平衡。(很明显)我试过分配不同的变量,但似乎无法找到答案。 我已经省略了中等难度和难难度的方法,因为它们现在是没有用的,直到我弄清楚这个。

    • 特别感谢JoãoCésar,这段as3代码创建了一个函数来生成SWF加载器。他使用增量值(count)在存储每个加载器动态信息的数组中循环迭代。在这种情况下,计数%SWFS.Length将导致0,1,0,1....在循环序列中有效地加载SWF。 这是一个想法: 代码如下:

    • 我需要创建一个方法来检查tictactoe游戏是否在玩、DRAW、XWIN或owin。然而,我很难编写代码来检查X或O是否获胜,因为游戏板的大小和获胜所需的大小(sizeWin)会根据用户的输入而改变。我被迫使用一维阵列的游戏板。我根本不知道从这里到哪里去。我最近的想法是使用嵌套的for循环来检查是否按行、列或对角线获得胜利,但我不确定如何实现它。如果有人对如何处理这个问题有任何提示,或者有任何其