package com.livermor.plusminus; // "livermor" Company Domain public class Bot { protected int[][] mMatrix; //digits for buttons protected boolean[][] mAllowedMoves; //, protected int mSize; // protected int mPlayerPoints = 0, mAiPoints = 0; // protected boolean mIsVertical; // protected int mCurrentActiveNumb; // ( 0 (mSize)) // private final static int CANT_GO_THERE = -1000; // , -1000 private final static int WORST_MOVE = -500; // , private final static int VICTORY_MOVE = 500; // , private final static int JACKPOT_INCREASE = 9; // , private static final int GOOD_ADVANTAGE = 6;// (), 6 int depth = 3; // 3 public Bot( int[][] matrix, boolean vertical ) { mMatrix = matrix; mSize = matrix.length; mIsVertical = vertical; } //, public int move( int playerPoints, int botPoints, boolean[][] moves, int activeNumb ) { mPlayerPoints = playerPoints; mAiPoints = botPoints; mCurrentActiveNumb = activeNumb; mAllowedMoves = moves; return calcMove(); } // public void setDepth(int depth) { this.depth = depth; } protected int calcMove() { // return calcBestMove(depth, mAllowedMoves, mCurrentActiveNumb, mIsVertical, mAiPoints, mPlayerPoints); } private int calcBestMove(int depth, boolean[][] moves, int lastMove, boolean isVert, int myPoints, int hisPoints) { int result = mSize; // , int[] moveRatings = new int[mSize]; // // , () if (depth == 1) return findMaxInRow(lastMove, isVert); else { int yMe, xMe; // int yHe, xHe; // for (int i = 0; i < mSize; i++) { // , (i) (lastMove) yMe = isVert ? i : lastMove; xMe = isVert ? lastMove : i; // , if (!mAllowedMoves[yMe][xMe]) { moveRatings[i] = CANT_GO_THERE; continue; // } int myNewP = myPoints + mMatrix[yMe][xMe];// moves[yMe][xMe] = false;// , // int hisBestMove = calcBestMove(depth - 1, moves, i, !isVert, hisPoints, myPoints); // , (.. ), .. if (hisBestMove == mSize) { if (myNewP > hisPoints) // , moveRatings[i] = VICTORY_MOVE; else // , moveRatings[i] = WORST_MOVE; moves[yMe][xMe] = true;// , continue; } // , yHe = isVert ? i : hisBestMove; xHe = isVert ? hisBestMove : i; int hisNewP = hisPoints + mMatrix[yHe][xHe]; moveRatings[i] = myNewP - hisNewP; // , // 1, if (depth - 1 != 1) { // hisBestMove = findMaxInRow(i, !isVert); yHe = isVert ? i : hisBestMove; xHe = isVert ? hisBestMove : i; hisNewP = hisPoints + mMatrix[yHe][xHe]; int jackpot = myNewP - hisNewP;// if (jackpot >= GOOD_ADVANTAGE) { // , moveRatings[i] = moveRatings[i] + JACKPOT_INCREASE; } } moves[yMe][xMe] = true;// , } // , . // , — ( ) int max = CANT_GO_THERE; for (int i = 0; i < mSize; i++) { if (moveRatings[i] > max) { max = moveRatings[i];// , result = i; } } } // return result; } // , () private int findMaxInRow(int lastM, boolean isVert) { int currentMax = -10; int move = mSize; int y = 0, x = 0; for (int i = 0; i < mSize; i++) { y = isVert ? i : lastM; x = isVert ? lastM : i; int temp = mMatrix[y][x]; if (mAllowedMoves[y][x] && currentMax <= temp) { currentMax = temp; move = i; } } return move; } }
package com.livermor.plusminus; import android.os.AsyncTask; import android.os.Handler; import java.util.Random; public class Game { // , public static final int mTimeToWait = 800; protected MyAnimation mAnimation; // AsyncTask // protected int[][] mMatrix; //digits for buttons protected volatile boolean[][] mAllowedMoves; protected int mSize; // protected int playerOnePoints = 0, playerTwoPoints = 0;// protected volatile boolean isRow = true; // protected volatile int currentActiveNumb; // protected ResultsCallback mResults;//, MainActivity protected volatile Bot bot;// Random rnd; // public Game(ResultsCallback results, int size) { mResults = results; // mSize = size; rnd = new Random(); generateMatrix(); // // , currentActiveNumb = rnd.nextInt(mSize); isRow = true; // ( ) for (int yPos = 0; yPos < mSize; yPos++) { for (int xPos = 0; xPos < mSize; xPos++) { // mResults.setButtonText(yPos, xPos, mMatrix[yPos][xPos]); if (yPos == currentActiveNumb) // mResults.changeButtonBg(yPos, xPos, isRow, true); } } bot = new Bot(mMatrix, true); } public void startGame() { activateRawOrColumn(true); } protected void generateMatrix() { mMatrix = new int[mSize][mSize]; mAllowedMoves = new boolean[mSize][mSize]; for (int i = 0; i < mSize; i++) { for (int j = 0; j < mSize; j++) { mMatrix[i][j] = rnd.nextInt(19) - 9; // -9 9 mAllowedMoves[i][j] = true; // } } } // MainActivity, public void OnUserTouchDigit(int y, int x) { mResults.onClick(y, x, true); activateRawOrColumn(false);// mAllowedMoves[y][x] = false; // playerOnePoints += mMatrix[y][x]; // mResults.changeLabel(false, playerOnePoints);// mAnimation = new MyAnimation(y, x, true, isRow);// mAnimation.execute(); isRow = !isRow; // currentActiveNumb = x; // , } // protected void onAnimationFinished() { if (!isRow) {// () // Handler, ui, // . Handel Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { botMove(); // } }, mTimeToWait / 2); } else // , activateRawOrColumn(true); } private void botMove() { // int botMove = bot.move(playerOnePoints, playerTwoPoints, mAllowedMoves, currentActiveNumb); if (botMove == mSize) {// , onResult(); // return; // } int y = botMove; // int x = currentActiveNumb; mAllowedMoves[y][x] = false; playerTwoPoints += mMatrix[y][x]; mResults.onClick(y, x, false); // mResults.changeLabel(true, playerTwoPoints); // mAnimation = new MyAnimation(y, x, true, isRow); // mAnimation.execute(); isRow = !isRow; // currentActiveNumb = botMove; // , } protected void activateRawOrColumn(final boolean active) { int countMovesAllowed = 0; // , int y, x; for (int i = 0; i < mMatrix.length; i++) { y = isRow ? currentActiveNumb : i; x = isRow ? i : currentActiveNumb; if (mAllowedMoves[y][x]) { // , mResults.changeButtonClickable(y, x, active); //, countMovesAllowed++; // , } } if (active && countMovesAllowed == 0) onResult(); } //: // — protected class MyAnimation extends AsyncTask<Void, Integer, Void> { int timeToWait = 35; // int y, x; boolean activate; boolean row; protected MyAnimation(int y, int x, boolean activate, boolean row) { this.activate = activate; this.row = !row; this.y = y; this.x = x; } @Override protected Void doInBackground(Void... params) { int downInc = row ? x - 1 : y - 1; int uppInc = row ? x : y; if (activate) sleep(Game.mTimeToWait);// if (activate) { // , while (downInc >= 0 || uppInc < mSize) { //Log.i(TAG, "while in Animation"); sleep(timeToWait); if (downInc >= 0) publishProgress(downInc--); // AsyncTask sleep(timeToWait); if (uppInc < mSize) publishProgress(uppInc++); } } else {// , int downInc2 = 0; int uppInc2 = mSize - 1; while (downInc2 <= downInc || uppInc2 > uppInc) { sleep(timeToWait); if (downInc2 <= downInc) publishProgress(downInc2++); sleep(timeToWait); if (uppInc2 > uppInc) publishProgress(uppInc2--); } } return null; } @Override protected void onProgressUpdate(Integer... values) { int numb = values[0]; int yPos = row ? y : numb; int xPos = row ? numb : x; // () if (activate) mResults.changeButtonBg(yPos, xPos, row, activate); else mResults.changeButtonBg(yPos, xPos, row, activate); } @Override protected void onPostExecute(Void aVoid) { if (activate) // , new MyAnimation(y, x, false, row).execute(); else //, , onAnimationFinished(); } // private void sleep(int time) { try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } } } protected void onResult() { // mResults.onResult(playerOnePoints, playerTwoPoints); } // MainActivity, ui //********************************************************************************* public interface ResultsCallback { // void changeLabel(boolean upLabel, int points); // void changeButtonBg(int y, int x, boolean row, boolean active); // void setButtonText(int y, int x, int text); // / void changeButtonClickable(int y, int x, boolean clickable); // void onResult(int one, int two); // void onClick(int y, int x, boolean flyDown); } }
<?xml version="1.0" encoding="utf-8"?> <!-- , package . , , >>> android:screenOrientation="portrait" --> <manifest package="com.livermor.plusminus" xmlns:android="http://schemas.android.com/apk/res/android"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary" >#7C7B7B</color> <color name="colorPrimaryDark" >#424242</color> <color name="colorAccent" >#FF4081</color> <color name="bgGrey" >#C4C4C4</color> <color name="bgRed" >#FC5C70</color> <color name="bgBlue" >#4A90E2</color> <color name="black" >#000</color> <color name="lightGreyBg" >#DFDFDF</color> <color name="white" >#fff</color> </resources>
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> </resources>
<resources> <dimen name="button.radius">10dp</dimen> <dimen name="sides">10dp</dimen> <dimen name="up_bottom">20dp</dimen> <dimen name="label_height">55dp</dimen> <dimen name="label_text_size">40dp</dimen> <dimen name="label_padding_sides">6dp</dimen> </resources>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/bgBlue"/> <corners android:bottomRightRadius="@dimen/button_radius" android:bottomLeftRadius="@dimen/button_radius" android:topLeftRadius="@dimen/button_radius" android:topRightRadius="@dimen/button_radius"/> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/bgRed"/> <corners android:bottomRightRadius="@dimen/button_radius" android:bottomLeftRadius="@dimen/button_radius" android:topLeftRadius="@dimen/button_radius" android:topRightRadius="@dimen/button_radius"/> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="@color/bgGrey"/> <corners android:bottomRightRadius="@dimen/button_radius" android:bottomLeftRadius="@dimen/button_radius" android:topLeftRadius="@dimen/button_radius" android:topRightRadius="@dimen/button_radius"/> </shape>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" tools:context="com.livermor.myapplication.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:background="@color/lightGreyBg"> <View android:id="@+id/center" android:layout_width="10dp" android:layout_height="1dp" android:layout_centerInParent="true"/> <TextView android:id="@+id/upper_scoreboard" android:background="@drawable/bg_red" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginLeft="@dimen/sides" android:layout_marginTop="15dp" android:layout_toLeftOf="@id/center" android:gravity="center_vertical|center_horizontal" android:paddingLeft="@dimen/label_padding_sides" android:paddingRight="@dimen/label_padding_sides" android:text=": 0" android:textColor="@color/white" android:textSize="@dimen/label_text_size"/> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/my_grid" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/upper_scoreboard" android:layout_gravity="center" android:foregroundGravity="center" android:layout_marginLeft="@dimen/sides" android:layout_marginRight="@dimen/sides" android:layout_marginBottom="@dimen/up_bottom" android:layout_marginTop="@dimen/up_bottom"/> <TextView android:id="@+id/lower_scoreboard" android:background="@drawable/bg_blue" android:layout_width="match_parent" android:layout_height="@dimen/label_height" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_below="@+id/my_grid" android:layout_marginBottom="15dp" android:layout_marginRight="15dp" android:layout_toRightOf="@id/center" android:gravity="center_vertical|center_horizontal" android:paddingLeft="@dimen/label_padding_sides" android:paddingRight="@dimen/label_padding_sides" android:text=": 0" android:textColor="@color/white" android:textSize="@dimen/label_text_size"/> </RelativeLayout> </RelativeLayout>
package com.livermor.plusminus; import android.content.Context; import android.util.AttributeSet; import android.widget.Button; public class MyButton extends Button { private MyOnClickListener mClickListener;// MainActivity int idX = 0; int idY = 0; //, public MyButton(Context context, int x, int y) { super(context); idX = x; idY = y; } public MyButton(Context context) { super(context); } public MyButton(Context context, AttributeSet attrs) { super(context, attrs); } public MyButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override // View public boolean performClick() { super.performClick(); mClickListener.OnTouchDigit(this);// return true; } public void setOnClickListener(MyOnClickListener listener){ mClickListener = listener; } public int getIdX(){ return idX; } public int getIdY(){ return idY; } // MainActivity //************************************ public interface MyOnClickListener { void OnTouchDigit(MyButton v); } }
package com.livermor.plusminus; import android.graphics.Typeface; import android.os.Handler; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.animation.AlphaAnimation; import android.view.animation.AnimationSet; import android.view.animation.TranslateAnimation; import android.widget.Button; import android.widget.GridLayout; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements Game.ResultsCallback, MyButton.MyOnClickListener { private static final int MATRIX_SIZE = 5;// 2 20)) //ui private TextView mUpText, mLowText; GridLayout mGridLayout; private MyButton[][] mButtons; private Game game; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGridLayout = (GridLayout) findViewById(R.id.my_grid); mGridLayout.setColumnCount(MATRIX_SIZE); mGridLayout.setRowCount(MATRIX_SIZE); mButtons = new MyButton[MATRIX_SIZE][MATRIX_SIZE];//5 5 // for (int yPos = 0; yPos < MATRIX_SIZE; yPos++) { for (int xPos = 0; xPos < MATRIX_SIZE; xPos++) { MyButton mBut = new MyButton(this, xPos, yPos); mBut.setTextSize(30-MATRIX_SIZE); Typeface boldTypeface = Typeface.defaultFromStyle(Typeface.BOLD); mBut.setTypeface(boldTypeface); mBut.setTextColor(ContextCompat.getColor(this, R.color.white)); mBut.setOnClickListener(this); mBut.setPadding(1, 1, 1, 1); // mBut.setAlpha(1); mBut.setClickable(false); mBut.setBackgroundResource(R.drawable.bg_grey); mButtons[yPos][xPos] = mBut; mGridLayout.addView(mBut); } } mUpText = (TextView) findViewById(R.id.upper_scoreboard); mLowText = (TextView) findViewById(R.id.lower_scoreboard); // mGridLayout mGridLayout.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { setButtonsSize(); // OnGlobalLayoutListener mGridLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); game = new Game(this, MATRIX_SIZE); // game.startGame(); // }//onCreate private void setButtonsSize() { int pLength; final int MARGIN = 6; int pWidth = mGridLayout.getWidth(); int pHeight = mGridLayout.getHeight(); int numOfCol = MATRIX_SIZE; int numOfRow = MATRIX_SIZE; // mGridLayout if (pWidth >= pHeight) pLength = pHeight; else pLength = pWidth; ViewGroup.LayoutParams pParams = mGridLayout.getLayoutParams(); pParams.width = pLength; pParams.height = pLength; mGridLayout.setLayoutParams(pParams); int w = pLength / numOfCol; int h = pLength / numOfRow; for (int yPos = 0; yPos < MATRIX_SIZE; yPos++) { for (int xPos = 0; xPos < MATRIX_SIZE; xPos++) { GridLayout.LayoutParams params = (GridLayout.LayoutParams) mButtons[yPos][xPos].getLayoutParams(); params.width = w - 2 * MARGIN; params.height = h - 2 * MARGIN; params.setMargins(MARGIN, MARGIN, MARGIN, MARGIN); mButtons[yPos][xPos].setLayoutParams(params); //Log.w(TAG, "process goes in customizeMatrixSize"); } } } //MyButton.MyOnClickListener //************************************************************************* @Override public void OnTouchDigit(MyButton v) { game.OnUserTouchDigit(v.getIdY(), v.getIdX()); } //Game.ResultsCallback //************************************************************************* @Override public void changeLabel(boolean upLabel, int points) { if (upLabel) mUpText.setText(String.format(": %d", points)); else mLowText.setText(String.valueOf(String.format(": %d", points))); } @Override public void changeButtonBg(int y, int x, boolean row, boolean active) { if (active) { if (row) mButtons[y][x].setBackgroundResource(R.drawable.bg_blue); else mButtons[y][x].setBackgroundResource(R.drawable.bg_red); } else { mButtons[y][x].setBackgroundResource(R.drawable.bg_grey); } } @Override public void setButtonText(int y, int x, int text) { mButtons[y][x].setText(String.valueOf(text)); } @Override public void changeButtonClickable(int y, int x, boolean clickable) { mButtons[y][x].setClickable(clickable); } @Override public void onResult(int playerOnePoints, int playerTwoPoints) { String text; if (playerOnePoints > playerTwoPoints) text = " "; else if (playerOnePoints < playerTwoPoints) text = " "; else text = ""; Toast.makeText(this, text, Toast.LENGTH_SHORT).show(); // 1500 run new Handler().postDelayed(new Runnable() { @Override public void run() { recreate(); // — MainActivity } }, 1500); } @Override public void onClick(final int y, final int x, final boolean flyDown) { final Button currentBut = mButtons[y][x]; currentBut.setAlpha(0.7f); currentBut.setClickable(false); AnimationSet sets = new AnimationSet(false); int direction = flyDown ? 400 : -400; TranslateAnimation animTr = new TranslateAnimation(0, 0, 0, direction); animTr.setDuration(810); AlphaAnimation animAl = new AlphaAnimation(0.4f, 0f); animAl.setDuration(810); sets.addAnimation(animTr); sets.addAnimation(animAl); currentBut.startAnimation(sets); new Handler().postDelayed(new Runnable() { @Override public void run() { currentBut.clearAnimation(); currentBut.setAlpha(0); } }, 800); } }
Source: https://habr.com/ru/post/271899/
All Articles