public void GetCellsTest() { int seedSize = 4; int rowSize = 2 * seedSize - 1; int candidatesAmount = seedSize; int cellsAmount = rowSize * rowSize; FutoshkService target = new FutoshkService(seedSize); Futoshiki actualCells = target.GetNewGrid(null); showFutoshiki(actualCells, rowSize); // check the cells amount Assert.AreEqual(cellsAmount, actualCells.Length); // to remove candidate from current cell after setting value // Assert.AreEqual(candidatesAmount-1,actualCells[0].Candidates.Length); // deal with related row // Assert.AreEqual(candidatesAmount - 1, actualCells[2].Candidates.Length); // deal with related column // Assert.AreEqual(candidatesAmount-1,actualCells[2*rowSize].Candidates.Length); // check a non-numeric cell Cell signCell = new Cell { Row = 1, Col = 8 }; Assert.AreEqual(signCell.IsNum, actualCells[rowSize].IsNum); }
/// <summary> /// Get a futoshiki grid. Every time user logged in, firstly checks the /// local xml file that named by user id. /// If there is no saved XML for current user then select DB. /// If got result from DB, then serialize to XML. /// </summary> /// <param name="userId">The id of current user who logged in</param> /// <returns>A futoshiki instance</returns> public Futoshiki GetGrid(string userId) { Futoshiki ready = null; if (null == userId) { return(ready); } try { ready = XmlHelper.Deserialize <Futoshiki>(userId, XmlHelper.U, _f.Scale.ToString()); } catch (Exception) { ready = _dao.Read(userId, _f.Scale.ToString()) as Futoshiki; if (null != ready) { ready.Status = (int)Futoshiki.Mode.Ongoing; XmlHelper.Serialize( ready, ready.Uid, XmlHelper.U, _f.Scale.ToString()); } } return(ready); }
public int Update(object o) { Futoshiki f = o as Futoshiki; if (f.Status == (int)Futoshiki.Mode.Completed) { //TODO: Update dbo.puzzel_Grids.Status throw new NotImplementedException(); } List <string> list = new List <string>(); string[] fields = new[] { Const.Val, Const.Uid, Const.Scale, Const.Gid, Const.Row, Const.Col }; for (int i = 0; i < f.Length; i++) { if (f[i].IsNum && f[i].IsWritable) { string[] values = new[] { "'" + f[i].Val + "'", "'" + f.Uid + "'", f.Scale.ToString(), "'" + f.Id + "'", f[i].Row.ToString(), f[i].Col.ToString() }; list.Add(BuildSql(Const.UpdtCells, fields, values)); } } return(ExecuteBatchUpdate(list.ToArray())); }
protected void BtnShowSolution(object sender, EventArgs e) { string fid = HidData.Value; Futoshiki f = _gridServ.GetSolution(fid); ShowFutoshiki(f); }
protected void BtnChkSlnClick(object sender, EventArgs e) { Futoshiki f = XmlHelper.Deserialize <Futoshiki>(HidData.Value); f.Uid = _uId; int count = _gridServ.CheckSolution(f); if (1 == count) { Msg("There is 1 incorrect cell."); } else if (count > 1) { Msg("There are " + count + " incorrect cells"); } else if (count < 0) { Msg("Cannot get data, please contact webmaster."); } else { Msg("Congratulations! You completely right!"); } ClientShow(f); }
private void ClientShow(Futoshiki f) { MsgDiv.Visible = true; //MsgDiv.Style["display"] = "block"; MsgDiv.Attributes.Add("onclick", "hidMsg()"); ShowFutoshiki(f); }
/// <summary> /// <li>The new game is first time saving, change status and let it to /// DB.</li><li>The ongoing game is serialize to a xml that named with /// user id.It does not need to connect DB every time. But the ongoing /// game may only be one for a free account.</li><li>The completed game /// is saving to DB.</li> /// </summary> /// <param name="f">A futoshiki object</param> /// <returns>bool</returns> public bool Save(Futoshiki f) { bool isSaved = false; int affectedRows; switch (f.Status) { case (int)Futoshiki.Mode.New: f.Status = (int)Futoshiki.Mode.Ongoing; affectedRows = _dao.Create(f); isSaved = affectedRows == f.Length ? true : false; break; case (int)Futoshiki.Mode.Ongoing: // serialize game for current user. isSaved = XmlHelper.Serialize(f, f.Uid, XmlHelper.U, f.Scale.ToString()); MoveSolution(f.Id); break; case (int)Futoshiki.Mode.Completed: affectedRows = _dao.Update(f); isSaved = -1 < affectedRows ? true : false; if (isSaved) { // delete cached futoshiki XmlHelper.Del(f.Uid, XmlHelper.U, f.Scale.ToString()); } break; default: break; } return(isSaved); }
public static Futoshiki CreateWikipediaFutoshiki() { Futoshiki wikipediaFutoshiki = new Futoshiki(); wikipediaFutoshiki.SetValue(0, 1, 4).SetValue(4, 1, 2).SetValue(2, 2, 4).SetValue(4, 3, 4); wikipediaFutoshiki.AddGreaterThan(0, 0, 1, 0).AddGreaterThan(2, 0, 3, 0).AddGreaterThan(3, 0, 4, 0). AddGreaterThan(4, 3, 3, 3).AddGreaterThan(1, 4, 0, 4).AddGreaterThan(2, 4, 1, 4); return(wikipediaFutoshiki); }
public static Futoshiki CreateFutoshiki() { Futoshiki futoshiki = new Futoshiki(); futoshiki.SetValue(4, 0, 3).SetValue(1, 3, 1).SetValue(0, 4, 1); futoshiki.AddGreaterThan(0, 0, 1, 0).AddGreaterThan(3, 1, 3, 0).AddGreaterThan(0, 1, 1, 1). AddGreaterThan(2, 1, 3, 1).AddGreaterThan(0, 3, 0, 2).AddGreaterThan(2, 4, 2, 3). AddGreaterThan(4, 4, 4, 3); return(futoshiki); }
public static void Main(string[] aargs) { int[,] input = new int[5, 5] { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 2 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 3 } }; var sut = new Futoshiki(); sut.SolvePuzzle(input); }
private void MoveSolution(string fid) { try { Futoshiki tempSolu = XmlHelper.Deserialize <Futoshiki>(fid, XmlHelper.S, XmlHelper.T); XmlHelper.Serialize(tempSolu, tempSolu.Id, XmlHelper.S); XmlHelper.Del(tempSolu.Id, XmlHelper.S, XmlHelper.T); } catch (FileNotFoundException fnfe) { Debug.WriteLine(GetType() + " - cannot find solution in temp folder" + fnfe); } }
private void ShowFutoshiki(Futoshiki f) { double n = 1.00 / f.Size; FutoshikiTable.Attributes.Add("status", f.Status.ToString()); FutoshikiTable.Attributes.Add("fid", f.Id); for (int r = 0; r < f.Size; r++) { TableRow tr = new TableRow(); for (int c = 0; c < f.Size; c++) { TableCell td = new TableCell { ID = r + "_" + c }; Unit u = new Unit(n.ToString("P")); td.Height = td.Width = u; int ind = r * f.Size + c; td.Text = f[ind].Val; td.Attributes.Add("row", r.ToString()); td.Attributes.Add("col", c.ToString()); if (f[ind].IsNum) { td.Attributes.Add("onclick", "onCellClick(this)"); td.Attributes.Add("isnum", "true"); td.CssClass = "number"; if (f[ind].IsWritable) { td.Attributes.Add("iswritable", "true"); } } else if (f[ind].IsHorizontalSign) { td.Attributes.Add("ishs", "true"); } else if (f[ind].IsVerticalSign) { td.Attributes.Add("isvs", "true"); } tr.Cells.Add(td); } FutoshikiTable.Rows.Add(tr); } }
private void UpdateRawSolution(bool isSuccess, string rawSolution) { if (!isSuccess) { return; } // update solution cache and serialize to xml file. Futoshiki raw = XmlHelper.Deserialize <Futoshiki>(rawSolution); for (int i = 0; i < _f.Length; i++) { if (_f[i].IsNum && raw[i].IsNum) { raw[i].IsWritable = _f[i].IsWritable; } } XmlHelper.Serialize(raw, raw.Id, XmlHelper.S, XmlHelper.T); }
private void showFutoshiki(Futoshiki f, int rowSize) { Console.WriteLine(""); int n = 0; for (int i = 0; i < f.Length; i++) { // if (actualCells[i].IsNum) // { Console.Write("{0, 3}", f[i].Val); n++; // } if (n == rowSize) { Console.WriteLine(""); n = 0; } } }
/// <summary> /// The folder named solution and temp both will be checked. /// After thant, if user logged and solution file in the temp folder, /// then move it out. /// </summary> /// <param name="f">a futoshiki object</param> /// <returns>incorrect count</returns> public int CheckSolution(Futoshiki f) { int count = 0; Futoshiki solution = GetSolution(f.Id); bool isOk = null != solution; if (!string.IsNullOrEmpty(f.Uid) && isOk) { MoveSolution(f.Id); } for (int i = 0; isOk && i < f.Length; i++) { if (f[i].IsNum && !solution[i].Val.Equals(f[i].Val)) { count++; } } return(isOk ? count : -1); }
protected void Page_Load(object sender, EventArgs e) { // initialize a Futoshiki service string scale = Request["ScaleList"]; size = string.IsNullOrEmpty(scale) ? size : int.Parse(scale); _gridServ = new FutoshkService(size); // get current user string u = User.Identity.Name; MembershipUser user = Membership.GetUser(u); MsgDiv.Visible = false; if (string.IsNullOrEmpty(u) || null == user) { SpanLogout.Visible = false; BtnSave.Attributes.Add("disabled", "true"); BtnSave.Style["cursor"] = "default"; ScaleList.Attributes.Add("disabled", "true"); } else { if (user.ProviderUserKey != null) { _uId = user.ProviderUserKey.ToString(); } SpanLogin.Visible = false; LblUsername.Text = string.Format( "{0}, Last login date is {1}", u, user.LastLoginDate); } if (!IsPostBack) { ScaleList.SelectedValue = size.ToString(); Futoshiki f = _gridServ.GetGrid(_uId) ?? _gridServ.GetNewGrid(_uId); ShowFutoshiki(f); } }
protected void BtnSaveClick(object sender, EventArgs e) { bool canSave = true; Futoshiki f = XmlHelper.Deserialize <Futoshiki>(HidData.Value); f.Uid = _uId; Debug.WriteLine(GetType() + " - " + f); /* * if f.status is set by -1, this actually is not a valid futoshiki * status code, just use this number to indicate that all cells are * finished but need check with solution yet. */ if (f.Status == -1) { // begin check with solution, let's set f.Status back to ongoing f.Status = (int)Futoshiki.Mode.Ongoing; int count = _gridServ.CheckSolution(f); if (count > 0) { canSave = false; } } if (canSave && _gridServ.Save(f)) { Msg("The game was successfully saved."); } else if (!canSave) { Msg("Your solution is not correct, please try harder!"); } else { Msg("Sorry, unsuccessful save, please try later."); } ClientShow(f); }
public int Create(object o) { Futoshiki f = o as Futoshiki; string[] sqls = new string[f.Length + 1]; string[] fields = new[] { Const.Id, Const.Uid, Const.Scale, Const.Status }; string[] values = new[] { "'" + f.Id + "'", "'" + f.Uid + "'", f.Scale.ToString(), f.Status.ToString() }; sqls[0] = BuildSql(Const.CrtGrid, fields, values); fields = new[] { Const.Gid, Const.Row, Const.Col, Const.Val, Const.IsWritable }; for (int i = 0; i < sqls.Length - 1; i++) { values = new[] { "'" + f.Id + "'", f[i].Row.ToString(), f[i].Col.ToString(), "'" + f[i].Val + "'", f[i].IsWritable ? 1.ToString() : 0.ToString() }; sqls[i + 1] = BuildSql(Const.CrtCell, fields, values); } return(ExecuteBatchUpdate(sqls)); }
public object Read(string uId, string scale) { Futoshiki f = null; string[] fields = new[] { Const.Uid, Const.Scale }; string[] values = new[] { "'" + uId + "'", scale }; // read ongoing game first string sql = BuildSql(Const.Read1, fields, values); SqlDataReader sdr = BeginQuery(sql); // read new game if cannot find ongoing game. if (!sdr.HasRows) { EndQuery(); sql = BuildSql(Const.Read0, fields, values); sdr = BeginQuery(sql); } for (int i = 0; sdr.Read(); i++) { if (null == f) { Byte s = sdr.GetByte(2); f = new Futoshiki(s); f.Status = sdr.GetByte(3); f.Id = sdr.GetGuid(1).ToString(); f.Uid = sdr.GetGuid(0).ToString(); } f[i].Row = sdr.GetInt32(4); f[i].Col = sdr.GetInt32(5); f[i].Val = sdr.GetString(6); f[i].IsWritable = sdr.GetBoolean(7); } EndQuery(); return(f); }
/// <summary> /// Get a futoshiki solution. now all solution is located file system. /// </summary> /// <param name="fid">futoshiki id</param> /// <returns>futoshiki object</returns> public Futoshiki GetSolution(string fid) { Futoshiki f = null; try { f = XmlHelper.Deserialize <Futoshiki>(fid, XmlHelper.S); } catch (FileNotFoundException) { try { f = XmlHelper.Deserialize <Futoshiki>(fid, XmlHelper.S, XmlHelper.T); } catch (FileNotFoundException fnfex) { Debug.WriteLine(GetType() + " - DID NOT FOUND SOLUTION "); Debug.WriteLine(fnfex); } } return(f); }
protected void ScaleListSelectedIndexChanged(object sender, EventArgs e) { Futoshiki f = _gridServ.GetGrid(_uId) ?? _gridServ.GetNewGrid(_uId); ShowFutoshiki(f); }
static void Main(string[] args) { Stopwatch sw = new Stopwatch(); Sudoku wikipediaSudoku = CreateWikipediaSudoku(); System.Console.WriteLine("Sudoku from the Wikipedia page https://en.wikipedia.org/wiki/Sudoku"); Solver.Console.Show(wikipediaSudoku.Values); wikipediaSudoku.Solve(); Solver.Console.Show(wikipediaSudoku.Values); sw.Reset(); sw.Start(); Killer wikipediaKiller = CreateWikipediaKiller(); System.Console.WriteLine("Killer from the Wikipedia page https://en.wikipedia.org/wiki/Killer_sudoku"); wikipediaKiller.Solve(); Solver.Console.Show(wikipediaKiller.Values); sw.Stop(); System.Console.WriteLine("Killer solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); sw.Reset(); sw.Start(); KenKen wikipediaKenKen = CreateWikipediaKenKen(); System.Console.WriteLine("KenKen from the Wikipedia page https://en.wikipedia.org/wiki/KenKen"); wikipediaKenKen.Solve(); Solver.Console.Show(wikipediaKenKen.Values); sw.Stop(); System.Console.WriteLine("KenKen solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); Futoshiki wikipediaFutoshiki = CreateWikipediaFutoshiki(); System.Console.WriteLine("Futoshiki from the Wikipedia page https://en.wikipedia.org/wiki/Futoshiki"); Solver.Console.Show(wikipediaFutoshiki.Values); wikipediaFutoshiki.Solve(); Solver.Console.Show(wikipediaFutoshiki.Values); sw.Reset(); sw.Start(); Kakuro wikipediaKakuro = CreateWikipediaKakuro(); System.Console.WriteLine("Kakuro from the Wikipedia page https://en.wikipedia.org/wiki/Kakuro"); wikipediaKakuro.Solve(); Solver.Console.Show(wikipediaKakuro.Values); sw.Stop(); System.Console.WriteLine("Kakuro solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); Sudoku sudoku = CreateSudoku1(); System.Console.WriteLine("Sudoku Mild No 9596 from the Times, 16th Jan 2018"); Solver.Console.Show(sudoku.Values); sudoku.Solve(); Solver.Console.Show(sudoku.Values); Sudoku sudoku2 = CreateSudoku2(); System.Console.WriteLine("Sudoku Difficult No 9597 from the Times, 16th Jan 2018"); Solver.Console.Show(sudoku2.Values); sudoku2.Solve(); Solver.Console.Show(sudoku2.Values); Sudoku sudoku3 = CreateSudoku3(); System.Console.WriteLine("Sudoku Super fiendish No 9598 from the Times, 16th Jan 2018"); Solver.Console.Show(sudoku3.Values); sudoku3.Solve(); Solver.Console.Show(sudoku3.Values); sw.Reset(); sw.Start(); Killer killer = CreateKiller(); System.Console.WriteLine("Killer Tough No 5820 from the Times, 16th Jan 2018"); killer.Solve(); Solver.Console.Show(killer.Values); sw.Stop(); System.Console.WriteLine("Killer solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); sw.Reset(); sw.Start(); KenKen kenKen = CreateKenKen(); System.Console.WriteLine("KenKen Medium No 4226 from the Times, 16th Jan 2018"); kenKen.Solve(); Solver.Console.Show(kenKen.Values); sw.Stop(); System.Console.WriteLine("KenKen solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); Futoshiki futoshiki = CreateFutoshiki(); System.Console.WriteLine("Futoshiki No 3087 from the Times, 16th Jan 2018"); Solver.Console.Show(futoshiki.Values); futoshiki.Solve(); Solver.Console.Show(futoshiki.Values); sw.Reset(); sw.Start(); Kakuro kakuro = CreateKakuro(); System.Console.WriteLine("Kakuro No 2046 from the Times, 16th Jan 2018"); kakuro.Solve(); Solver.Console.Show(kakuro.Values); sw.Stop(); System.Console.WriteLine("Kakuro solution took " + sw.ElapsedMilliseconds / 1000.0 + " seconds"); System.Console.WriteLine(); System.Console.ReadLine(); }
public void testMethod1() { var sut = new Futoshiki(); }
/// <summary> /// The constructor can create a grid of any size by given seed number. /// </summary> /// <param name="size"></param> public FutoshkService(int size) { _f = new Futoshiki(size); _rdm = new Random(); _dao = new FutoshikiDao(); }