⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.java

📁 Sudoku游戏的原代码,以aop方式进行修改
💻 JAVA
字号:
/**
* Copyright 2005 Victor Ferrer
* 
* This file is part of FreeSudoku.
* 
* FreeSudoku is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* 
* FreeSudoku is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with FreeSudoku; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*
*/

package org.gos.freesudoku;

import java.util.*;

public class Game
{
	private int[][] 	cPos 			= null;		// posicion en la partida.
	private int[][] 	cRes 			= null;		// posicion del resultado.
	private boolean[][]	cInitPos		= null;		// posiciones mostradas inicialmente.
//	private int			cNivel 			= -50;
	private int			cNivel 			= 5;
	private int			cPosFilled		= 0;
	private Random 		cGenerator		= null;
	private boolean		isSymmetric		= true;
    private Solver 		solver 			= null;

	
	protected Game()
	{
		cPos = new int[9][9];
		cRes = new int[9][9];
		cInitPos = new boolean[9][9];
		cGenerator = new Random();
		solver = new Solver();
	}

	protected void initPartida(int pNivel, boolean pIsSymmetric)
	{
		cNivel = pNivel;
		isSymmetric = pIsSymmetric;
		// int numRes = 0;
		int maxDiff = -1;
        int maxRes[][] = null;
        int maxPos[][] = null;
        boolean found = false;
        
		for (int part = 0; part < 2+cNivel/2; part++)
        {
            clearArray(cRes);
            generatePartida(0);
            for (int pos = 0; pos < 2+cNivel*2; pos++)
            {
                generateInitPos();
                solver.loopAllStg();
                CONSTS.log(solver.strategiesUsed);
                CONSTS.log("initPartida Diff: " + solver.difficulty);
                if( cNivel == 1)
                {
                    if( solver.difficulty >=  0 && solver.difficulty < 10)
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                        found = true;
                        break;
                    }
                    if( (maxDiff == -1) || Math.abs( maxDiff-0) > Math.abs(solver.difficulty-0))
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                    }
                }

                if( cNivel == 2)
                {
                    if( solver.difficulty >= 10 && solver.difficulty < 30)
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                        found = true;
                        break;
                    }
                    if( (maxDiff == -1) || Math.abs( maxDiff-25) > Math.abs(solver.difficulty-25))
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                    }
                }

                if( cNivel == 3)
                {
                    if( solver.difficulty >= 20 && solver.difficulty < 50)
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                        found = true;
                        break;
                    }
                    if( (maxDiff == -1) || Math.abs( maxDiff-45) > Math.abs(solver.difficulty-45))
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                    }
                }

                if( cNivel == 4 )
                {
                    if( maxDiff < solver.difficulty)
                    {
                        maxDiff = solver.difficulty;
                        maxRes = Solver.dupArray( cRes);
                        maxPos = Solver.dupArray( cPos);
                    }
                }
                if( found) break;
            }
            if( found) break;
        }
        CONSTS.log(" * * * * * * * * * * * * maxDiff: " +  maxDiff);
        if (maxRes != null)
        {
            cRes = maxRes;
            cPos = maxPos;
            cPosFilled = 0;
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                	if(cPos[i][j] != 0)
                	{
                		cInitPos[i][j] = true;
                		cPosFilled++;
                	}
                }
            }
        }

	}
	
    private void generateInitPos()
    {
        int maxPosToFill = 33 - cNivel*3;
        boolean[] used = new boolean[81];
        int usedCount = 81;

        solver.setMatriu( cRes);
        Arrays.fill( used, false);
        while ( solver.getFilled() > maxPosToFill && usedCount > 1)
        {
            int i = cGenerator.nextInt( 81);
            do
            {
                if( i < 80 ) i++;
                else i = 0;
            } while( used[i]);
            
            used[i] = true;
            usedCount--;
            solver.clearVal( i/9, i%9);
            if ( isSymmetric && (i/9 != 4 || i%9 != 4 ))
            {
                solver.clearVal( 8 - i/9, 8 - i%9);
                used[ 9*(8-i/9) + (8 - i%9) ] = true;
                usedCount--;
            }
            solver.fillPosVals();
            int sols = solver.findAllSols( -1, true);
            if( sols > 1)
            {
                solver.setVal( i/9, i%9, cRes[i/9][i%9]);
        		if (isSymmetric && (i/9 != 4 || i%9 != 4 ))
        		{
        			solver.setVal( 8-i/9, 8-i%9, cRes[8 - i/9][8 - i%9]);
        		}
            }
        }

        cPos = Solver.dupArray( solver.getMatriu());
        // cPosFilled = solver.getFilled();
    }

    private boolean generatePartida(int pPos)
	{
		// CONSTS.log( taulerToString( cRes) + "\n");
		// CONSTS.log( pPos);
		if( pPos == 9*9 ) return true;
		ArrayList posibleVals = getAllCorrectVals( pPos/9, pPos%9);
		if( posibleVals.isEmpty()) return false;
		
		while( !posibleVals.isEmpty())
		{
			int candidate = cGenerator.nextInt( posibleVals.size());
			cRes[pPos/9][pPos%9] = ((Integer )posibleVals.get( candidate)).intValue();
			if( isCorrect( pPos/9, pPos%9, cRes[pPos/9][pPos%9]))
			{
				if( generatePartida( pPos + 1)) 
				{
					return true;
				}
			}
			posibleVals.remove( candidate);
		}
		cRes[pPos/9][pPos%9] = 0;
		// CONSTS.log(" --------- ");
		return false;
	}
	
	protected ArrayList getAllLegalVals( int i, int j)
	{
		return getCorrectValsForArray( i, j, cPos);
	}

	private ArrayList getAllCorrectVals( int i, int j)
	{
		return getCorrectValsForArray( i, j, cRes);
	}

	protected static ArrayList getCorrectValsForArray( int i, int j, int[][] pArray)
	{
		ArrayList res = new ArrayList();
        if( pArray[i][j] != 0) return res;
		for (int val = 1; val <= 9; val++)
		{
			if( isCorrect( i, j, val, pArray))
				res.add( new Integer( val));
		}
		return res;
	}

	private void clearArray( int[][] pArray)
	{
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				pArray[i][j] = 0;
			}
		}
	}

	protected int[][] getPos()
	{
		return cPos;
	}

	protected boolean isLegal( int i, int j, int val)
	{
		if( val == 0) return true;
		return isCorrect( i, j, val, cPos);
	}
	
	private boolean isCorrect( int i, int j, int val)
	{
		if( val == 0) return false;
		return isCorrect( i, j, val, cRes);
	}

	protected static boolean isCorrect( int i, int j, int val, int[][] pArray)
	{
		// CONSTS.log("isCorrect() " + i + " " + j + " " + val);
		for(int x = 0; x < 9; x++)
		{
			if( pArray[i][x] == val && x != j) return false;
			if( pArray[x][j] == val && x != i) return false;
		}
		
		for(int x = i - i%3; x < i - i%3 + 3; x++)
		{
			for(int y = j - j%3; y < j - j%3 + 3; y++)
			{
				if( pArray[x][y] == val && ( x != i || y != j)) return false;
			}
		}
		
		return true;
	}

	protected String arrayToString( int[][] pArray)
	{
		StringBuffer res = new StringBuffer();
		for (int i = 0; i < 9; i++)
		{
			for (int j = 0; j < 9; j++)
			{
				res.append( " " + pArray[i][j]);
			}
			res.append("\n");
		}
		return res.toString();
	}

	protected void setPosVal(int i, int j, int val)
	{
		if( 		cPos[i][j] == 0 && val != 0) cPosFilled++;
		else if( 	cPos[i][j] != 0 && val == 0) cPosFilled--;
		cPos[i][j] = val;
		CONSTS.log("cPosFilled " + cPosFilled);
//		int cont = 0;
//		for (int n = 0; n < 9; n++)
//		{
//			for (int m = 0; m < 9; m++)
//			{
//				if( cPos[n][m] != 0) cont++;
//			}
//		}
//		if( cont != cPosFilled)
//			throw new RuntimeException("Game.setPosVal(i,j,val) " + i + " " + j + " " + val + " cPos[i][j] " + cPos[i][j] +
//					" cPosFilled: " + cPosFilled + " cont: " + cont);
	}

	protected boolean[][] getInitPos()
	{
		return cInitPos;
	}

	protected boolean resolved()
	{
		return cPosFilled == 9*9;
	}
	
	// for testing
	public String toString()
	{
		return arrayToString( cRes);
	}
	
	//Add for Save&Load
	public void setInitPos(String key) {

		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				cInitPos[i][j] = FreeSudoku.intToBoolean(Integer.parseInt(String.valueOf(key.charAt(i* 9 + j))));
				//cInitPos[i][j] = Boolean.getBoolean(String.valueOf(key.charAt(i* 9 + j)));
			}
		}

	}

	public String cPosToString() {
		return Solver.matriuToKey(cPos);

	}

	public String cResToString() {
		return Solver.matriuToKey(cRes);
	}

	// --
	public void cPosFromString(String key) {
		cPos = Solver.matriuFromKey(key);
	}

	public void cResFromString(String key) {
		cRes = Solver.matriuFromKey(key);
	}
	public int getCNivel(){
		return cNivel;
	}
	public void setCNivel(int nivel){
		this.cNivel= nivel;
	}
	public int getCPosFilled(){
		return cPosFilled;
	}
	public void setCPosFilled(int fill){
		this.cPosFilled = fill;
	}
	public boolean getIsSymmetric(){
		return this.isSymmetric;
	}
	public void setIsSymmetric(boolean sym){
		this.isSymmetric =sym;
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -