import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class Numbers extends Applet implements ItemListener,
MouseListener,ActionListener{
int X0=50,Y0=50;
int SIZE=50;
int[][] prob={{1,0,0,0,4,0,0,0,3}, //アプレット起動時のサンプル問題
{0,3,0,7,0,1,0,2,0},
{0,0,6,0,8,0,7,0,0},
{0,0,8,1,0,0,6,0,0},
{0,1,0,0,0,0,0,3,0},
{0,0,2,0,0,9,8,0,0},
{0,0,5,0,2,0,1,0,0},
{0,7,0,9,0,6,0,5,0},
{9,0,0,0,5,0,0,0,7}};
int[][] solu=new int[9][9];
int[][] trial=new int[9][9];
int[][] gray=new int[9][9];
int[] number=new int[10];
Button button_solu_reset,button_trial_reset,button_all_reset;
CheckboxGroup group1=new CheckboxGroup();
CheckboxGroup group2=new CheckboxGroup();
Checkbox[] radio1=new Checkbox[10];
Checkbox[] radio2=new Checkbox[3];
Font font0=new Font("",Font.PLAIN,SIZE/2); //モード表示用フォント
Font font1=new Font("",Font.PLAIN,SIZE); //問題用フォント
Font font2=new Font("",Font.ITALIC,SIZE); //解答、試行用フォント
Font font3=new Font("",Font.PLAIN,SIZE/3); //候補表示用フォント
int selected_number; //ラジオボタンで選ばれた数字
public void init(){
//数字入力用ラジオボタン
add(radio1[0]=new Checkbox("取消",group1,true));
for(int i=1;i<10;i++)
add(radio1[i]=new Checkbox(String.valueOf(i),group1,false));
for(int i=0;i<10;i++)
radio1[i].addItemListener(this);
//モード選択用ラジオボタン
add(radio2[0]=new Checkbox("出題",group2,false));
//起動時には解答モードにしておく
add(radio2[1]=new Checkbox("解答",group2,true));
add(radio2[2]=new Checkbox("試行",group2,false));
for(int i=0;i<3;i++)
radio2[i].addItemListener(this);
//ボタンの設定
add(button_all_reset=new Button("全クリヤ"));
add(button_solu_reset=new Button("解答クリヤ"));
add(button_trial_reset=new Button("試行クリヤ"));
button_all_reset.addActionListener(this);
button_solu_reset.addActionListener(this);
button_trial_reset.addActionListener(this);
addMouseListener(this);
}
//ボタンがクリックされた際のメソッド
public void actionPerformed(ActionEvent ae){
if(ae.getSource()==button_all_reset){ //[全クリヤ]
radio1[0].setState(true); //[取消]に設定
radio2[0].setState(true); //[出題]に設定
for(int j=0;j<9;j++)
for(int i=0;i<9;i++){ //問題、解答、試行をクリヤ
prob[j][i]=0;
solu[j][i]=0;
trial[j][i]=0;
}
}
if(ae.getSource()==button_solu_reset){ //[解答クリヤ]
for(int j=0;j<9;j++)
for(int i=0;i<9;i++){ //解答、試行をクリヤ
solu[j][i]=0;
trial[j][i]=0;
}
}
if(ae.getSource()==button_trial_reset){ //[試行クリヤ]
for(int j=0;j<9;j++)
for(int i=0;i<9;i++){ //試行をクリヤ
trial[j][i]=0;
}
}
repaint();
}
//ラジオボタンが変更になったときのメソッド
public void itemStateChanged(ItemEvent ie){
for(int i=0;i<10;i++){ //選択された数字でselected_numberを設定
if(radio1[i].getState()){
selected_number=i;
break;
}
}
repaint();
}
//マウスがクリックされたときのメソッド
public void mouseClicked(MouseEvent me){
int i,j;
int x=me.getX();
int y=me.getY();
if(x>=X0 && x<=X0+SIZE*9 && y>=Y0 && y<=Y0+SIZE*9){ //枠の範囲内
i=(x-X0)/SIZE;
j=(y-Y0)/SIZE;
//出題モード --- グレイ以外で設定できる
if(radio2[0].getState()){
if(gray[j][i]==0)
prob[j][i]=selected_number;
else
Toolkit.getDefaultToolkit().beep(); //ビープ音を鳴らす
}
//解答モード --- 問題、グレイ以外で設定できる
if(radio2[1].getState()){
if(prob[j][i]==0 && gray[j][i]==0)
solu[j][i]=selected_number;
else
Toolkit.getDefaultToolkit().beep(); //ビープ音を鳴らす
}
//試行モード --- 問題、グレイ、解答以外で設定できる
if(radio2[2].getState()){
if(prob[j][i]==0 && gray[j][i]==0 && solu[j][i]==0)
trial[j][i]=selected_number;
else
Toolkit.getDefaultToolkit().beep(); //ビープ音を鳴らす
}
repaint();
}
}
public void mousePressed(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}
public void paint(Graphics g){
int i,j,ii,jj,k;
int x,y;
int single_number=0;
//モードを表示する
g.setFont(font0);
if(radio2[0].getState()){
g.setColor(Color.black);
g.drawString("出題モード",X0+SIZE*10,Y0+50);
}
else if(radio2[1].getState()){
g.setColor(Color.blue);
g.drawString("解答モード",X0+SIZE*10,Y0+50);
}
else if(radio2[2].getState()){
g.setColor(Color.red);
g.drawString("試行モード",X0+SIZE*10,Y0+50);
}
//枠を描く
g.setColor(Color.black);
for(j=0;j<10;j++){
g.drawLine(X0+j*SIZE,Y0,X0+j*SIZE,Y0+SIZE*9);
if(j % 3 ==0) //線を太くする
g.drawLine(X0+1+j*SIZE,Y0,X0+1+j*SIZE,Y0+SIZE*9);
}
for(i=0;i<10;i++){
g.drawLine(X0,Y0+i*SIZE,X0+SIZE*9,Y0+i*SIZE);
if(i % 3 ==0) //線を太くする
g.drawLine(X0,Y0+1+i*SIZE,X0+SIZE*9,Y0+1+i*SIZE);
}
//グレイ領域をクリヤ
for(j=0;j<9;j++)
for(i=0;i<9;i++)
gray[j][i]=0;
//[取消]ボタン以外の場合にグレイ領域を設定する
if(selected_number!=0){
//グレイ領域を設定
for(j=0;j<9;j++)
for(i=0;i<9;i++){
if(prob[j][i]==selected_number ||
solu[j][i]==selected_number ||
trial[j][i]==selected_number){
//横方向をグレイ表示
jj=j;
for(ii=0;ii<9;ii++)
gray[jj][ii]=1;
//縦方向をグレイ表示
ii=i;
for(jj=0;jj<9;jj++)
gray[jj][ii]=1;
//サブグリッドをグレイ表示
for(jj=j-(j % 3);jj<j-(j % 3)+3;jj++)
for(ii=i-(i % 3);ii<i-(i % 3)+3;ii++)
gray[jj][ii]=1;
}
}
//グレイ領域を色付けする
g.setColor(new Color(208,208,208));
for(j=0;j<9;j++)
for(i=0;i<9;i++){
if(gray[j][i]==1)
g.fillRect(X0+2+i*SIZE,Y0+2+j*SIZE,SIZE-3,SIZE-3);
}
}
//入力可能な数字を表示する
for(j=0;j<9;j++)
for(i=0;i<9;i++){
//数字が入っていない
if(prob[j][i]==0 && solu[j][i]==0 && trial[j][i]==0){
for(k=0;k<10;k++)
number[k]=0;
//横方向を調べる
jj=j;
for(ii=0;ii<9;ii++){
number[prob[jj][ii]]=1;
number[solu[jj][ii]]=1;
number[trial[jj][ii]]=1;
}
//縦方向を調べる
ii=i;
for(jj=0;jj<9;jj++){
number[prob[jj][ii]]=1;
number[solu[jj][ii]]=1;
number[trial[jj][ii]]=1;
}
//サブグリッドを調べる
for(jj=j-(j % 3);jj<j-(j % 3)+3;jj++)
for(ii=i-(i % 3);ii<i-(i % 3)+3;ii++){
number[prob[jj][ii]]=1;
number[solu[jj][ii]]=1;
number[trial[jj][ii]]=1;
}
//入力可能な数字(無かった数字)をマスの中に表示する
g.setFont(font3);
g.setColor(Color.black);
int n=0;
for(k=1;k<10;k++){
if(number[k]!=1){
x=X0+i*SIZE+5+((k-1) % 3)*SIZE/3;
y=Y0+j*SIZE+SIZE/3+((k-1)/3)*SIZE/3;
g.drawString(String.valueOf(k),x,y);
single_number=k;
n++;
}
}
//入力可能な数字が一個の場合は、
//解答または試行として確定する
if(n==1){
if(radio2[1].getState()){
solu[j][i]=single_number;
repaint();
}
if(radio2[2].getState()){
trial[j][i]=single_number;
repaint();
}
}
}
}
//グリッドに数字を描画する
for(j=0;j<9;j++)
for(i=0;i<9;i++){
x=X0+(int)(0.2*SIZE)+i*SIZE;
y=Y0+(int)(0.9*SIZE)+j*SIZE;
//問題を描画する
g.setFont(font1);
if(prob[j][i]!=0){
g.setColor(Color.black);
g.drawString(String.valueOf(prob[j][i]),x,y);
}
g.setFont(font2);
//解答を描画する
if(solu[j][i]!=0){
g.setColor(Color.blue);
g.drawString(String.valueOf(solu[j][i]),x,y);
}
//試行を描画する
if(trial[j][i]!=0){
g.setColor(Color.red);
g.drawString(String.valueOf(trial[j][i]),x,y);
}
}
}
}