// sudoku.code




void main(){
	var nameDll="Server.dll";
	LoadDLL(nameDll);
	SendDLL(nameDll,"newserver");
	SendDLL(nameDll,"setport(8959)");
	var str="setexe:\""+WAY+"\\SYS\\SAFlashPlayer.exe\" "+WAY+"\\code\\example\\Sudoku\\Sudaku.swf";
	SendDLL(nameDll,str);
	SendDLL(nameDll,"connect");
	trace("connect ok.");
	while(1){
		SendDLL(nameDll,"slux");
		str=Recv1DLL(nameDll);
		if(str=="exit"){
			SendDLL(nameDll,"send:{comand}");
			SendDLL(nameDll,"send:quit");
			break;
			}
		if(str=="game")rungame(nameDll);
		if(str=="getMaps")getMaps(nameDll);
		if(str=="saveAdd")saveAdd(nameDll);
		if(str=="deleteMap")deleteMap(nameDll);
		if(str=="resave");else continue;
		resave(nameDll);
		continue;
		}
}



void resave(var nameDll){
	SendDLL(nameDll,"slux");
	n=Recv1DLL(nameDll);
	SendDLL(nameDll,"slux");
	str=Recv1DLL(nameDll);
	str="m.push_back("+str.export()+");";
	var f=getFunction("getAllLevels");
	var pos=f.Root();
	pos=f.Next(pos);
	pos=f.Next(pos);
	int i=0;
	for(;i<n;++i)pos=f.Next(pos);;
	pos.insertDown(str);
	pos=f.Next(pos);
	pos=f.Next(pos);
	f.delete(pos);
	trace("resave matrex");
}



void deleteMap(var nameDll){
	SendDLL(nameDll,"slux");
	n=Recv1DLL(nameDll);
	var f=getFunction("getAllLevels");
	var pos=f.Root();
	pos=f.Next(pos);
	pos=f.Next(pos);
	pos=f.Next(pos);
	int i=0;
	for(;i<n;++i)pos=f.Next(pos);;
	pos.delete();
}



void saveAdd(var nameDll){
	SendDLL(nameDll,"slux");
	str=Recv1DLL(nameDll);
	str="m.push_back("+str.export()+");";
	var n=getAllLevels().length();
	var f=getFunction("getAllLevels");
	var pos=f.Root();
	pos=f.Next(pos);
	pos=f.Next(pos);
	int i=0;
	for(;i<n;++i)pos=f.Next(pos);;
	pos.insertDown(str);
	trace("Save new matrex.");
}



void getMaps(var nameDll){
	trace("get Levels");
	var m=getAllLevels();
	if(!m.length())return;
	SendDLL(nameDll,"send:{comand,List}");
	SendDLL(nameDll,"send:setLevels");
	string str="[";
	int i=0;
	while(i<m.length()){
		if(i)str+=",";
		str+="x";
		++i;
		}
	str+="]";
	SendDLL(nameDll,"send:"+str);
	i=0;
	while(i<m.length()){
		SendDLL(nameDll,"send:"+m[i].export());
		++i;
		}
}



var getAllLevels(){
	var m={};
	m.push_back("004300617870000050000020008040093005590040083300510090100050000060000032987002500");
	return m;
}



void rungame(var nameDll){
	var starttime=getTime();
	SendDLL(nameDll,"slux");
	str=Recv1DLL(nameDll);
	var f=getFunction("gogame");
	pos=f.Next(pos);
	int n=createNewLaver();
	int p=createNewProcess(n,f);
	setValueInLaver(n,p,"str",str);
	runLaver(n);
	var NP=getVariantov(n);
	if(NP>0){
		var m=getValuesInLaver(n,"m");
		m=m[0];
		SendDLL(nameDll,"send:{comand,Result}");
		SendDLL(nameDll,"send:setResult");
		SendDLL(nameDll,"send:"+OutStr(&m).export());
		}else trace("No solutions.");
	trace("time:"+timeFormat(getTime()-starttime));
}



var initSudaku(var* m,string s){
	( *m)=reserve(9);
	int k=0;
	int i=0;
	while(i<9){
		(*m)[i]=reserve(9);
		int j=0;
		while(j<9){
			(*m)[i][j]=s[(k++)];
			++j;
			}
		++i;
		}
}



bool proba(var* m,int x,int y,int p){
	int j;
	int i=0;
	while(i<9){
		if((*m)[y][i]==p)return 0;
		++i;
		}
	i=0;
	while(i<9){
		if((*m)[i][x]==p)return 0;
		++i;
		}
	x=((int)(x/3));
	y=((int)(y/3));
	x*=3;
	y*=3;
	i=0;
	while(i<3){
		j=0;
		while(j<3){
			if((*m)[y+i][x+j]==p)return 0;
			++j;
			}
		++i;
		}
	return 1;
}



int one(var* m){
	int x;
	int y;
	int ok=0;
	y=0;
	while(y<9){
		x=0;
		while(x<9){
			if((*m)[y][x]=='0'){
				var s={};
				int p=1;
				while(p<10){
					if(proba(m,x,y,p+'0'))s+={p+'0'};
					++p;
					}
				if(s.size()==1){
					++ok;
					(*m)[y][x]=((char)s[0]);
					trace("x="+x+" y="+y+" p="+(s[0]-'0'));
					}
				}
			++x;
			}
		++y;
		}
	return ok;
}



var Out(var* m){
	string str="";
	int x;
	int y;
	y=0;
	while(y<9){
		x=0;
		while(x<9){
			str+=(*m)[y][x];
			++x;
			}
		str+="\n";
		++y;
		}
	return str;
}



var OutStr(var* m){
	string str="";
	int x;
	int y;
	y=0;
	while(y<9){
		x=0;
		while(x<9){
			str+=(*m)[y][x];
			++x;
			}
		++y;
		}
	return str;
}



void gogame(string str){
	setPrioritetProcess("end");
	var m;
	initSudaku(&m,str);
	trace(Out(&m));
	while(one(&m));
	int x;
	int y;
	y=0;
	while(y<9){
		x=0;
		while(x<9){
			if(m[y][x]=='0'){
				var s={};
				int p=1;
				while(p<10){
					if(proba(&m,x,y,p+'0'))s+={p+'0'};
					++p;
					}
				if(s.size()==0)OFF;
				m[y][x]=((char)s[rozpad([0;s.size()).getN())]);
				}
			++x;
			}
		++y;
		}
	trace(Out(&m));
	define();
}


// sudoku.code	:-|