public VariantSelectionModel(VariantVersion version) { Name = version.Variant.Name; VariantID = version.VariantID; VersionID = version.ID; NumPlayers = version.Variant.PlayerCount; }
public VersionSelectionModel(VariantVersion version, bool isPublic, bool canDelete) { Name = VariantService.DescribeVersion(version); VersionID = version.ID; IsPublic = isPublic; CanDelete = canDelete; }
public bool CanDelete(VariantVersion version) { // versions can be deleted only if they are associated with no games at all, active or otherwise. // public versions can not be deleted. return !version.Games.Any() && (!version.Variant.PublicVersionID.HasValue || version.Variant.PublicVersionID != version.ID) && version.Variant.AllVersions.Count > 1; }
public VariantDefinition(VariantVersion version) { XmlDocument doc = new XmlDocument(); if (version.Definition != string.Empty) doc.LoadXml(version.Definition); else doc.LoadXml("<game><board viewBox=\"0 0 100 100\"/></game>"); Version = version; Xml = doc; }
public BoardShapeModel(VariantVersion version, XmlDocument boardSvg, string linkData) { VariantName = version.Variant.Name; SvgData = boardSvg.OuterXml; LinkData = linkData; ThisPage = "Shape"; NextPage = "Global dirs"; NextPageTooltip = "links between cells"; }
public PieceDefinitionsModel(VariantVersion version, XmlNode pieceData) { VariantName = version.Variant.Name; PieceData = pieceData != null ? pieceData.OuterXml : "<Pieces />"; PrevPage = "Cell refs"; ThisPage = "Piece types"; NextPage = "Initial layout"; PrevPageTooltip = "unique references for each cell"; NextPageTooltip = "Piece starting positions"; }
public VariantVersion CreateNewVersion(VariantVersion version) { var newestVersion = version.Variant.AllVersions.OrderByDescending(v => v.Number).FirstOrDefault(); int versionNum = newestVersion == null ? 1 : newestVersion.Number + 1; var newVersion = Entities.Entry(version).GetDatabaseValues().ToObject() as VariantVersion; newVersion.LastModified = DateTime.Now; newVersion.Number = (short)versionNum; Entities.VariantVersions.Add(newVersion); Entities.SaveChanges(); return newVersion; }
public DirectionGroupsModel(VariantVersion version, string allDirs, string groupData) { VariantName = version.Variant.Name; AllDirs = allDirs; GroupData = groupData; PrevPage = "Relative dirs"; ThisPage = "Dir groups"; NextPage = "Cell refs"; PrevPageTooltip = "relative directions"; NextPageTooltip = "unique references for each cell"; }
public GlobalDirectionsModel(VariantVersion version, XmlDocument boardSvg, string linkData) { VariantName = version.Variant.Name; SvgData = boardSvg.OuterXml; LinkData = linkData; PrevPage = "Shape"; ThisPage = "Global dirs"; NextPage = "Relative dirs"; PrevPageTooltip = "board layout"; NextPageTooltip = "relative directions"; }
public RelativeDirectionsModel(VariantVersion version, string globalDirs, string relativeLinks) { VariantName = version.Variant.Name; GlobalDirectionsDiagram = globalDirs; RelativeDirections = relativeLinks; PrevPage = "Global dirs"; ThisPage = "Relative dirs"; NextPage = "Dir groups"; PrevPageTooltip = "links between cells"; NextPageTooltip = "grouping directions together"; }
public CellReferencesModel(VariantVersion version, XmlDocument boardSvg, string links, IEnumerable<string> dirs) { VariantName = version.Variant.Name; SvgData = boardSvg.OuterXml; LinkData = links; AllDirs = dirs; PrevPage = "Dir groups"; ThisPage = "Cell refs"; NextPage = "Piece types"; PrevPageTooltip = "grouping directions together"; NextPageTooltip = "Piece definitions"; }
public CellReferencesModel(VariantVersion version, XmlDocument boardSvg, string links, IEnumerable <string> dirs) { VariantName = version.Variant.Name; SvgData = boardSvg.OuterXml; LinkData = links; AllDirs = dirs; PrevPage = "Dir groups"; ThisPage = "Cell refs"; NextPage = "Piece types"; PrevPageTooltip = "grouping directions together"; NextPageTooltip = "Piece definitions"; }
public VariantDefinition(VariantVersion version) { XmlDocument doc = new XmlDocument(); if (version.Definition != string.Empty) { doc.LoadXml(version.Definition); } else { doc.LoadXml("<game><board viewBox=\"0 0 100 100\"/></game>"); } Version = version; Xml = doc; }
public GamePlayModel(VariantVersion version, GameMode mode) { Tag = version.Variant.Tag; Help = version.Variant.HelpText; if (string.IsNullOrEmpty(Help)) Help = "No help text has been specified for this variant."; if (version.Variant.PublicVersionID.HasValue && version.ID == version.Variant.PublicVersionID) Name = version.Variant.Name; else { Name = string.Format("{0} v{1}", version.Variant.Name, version.Number); Version = version.Number; } Mode = mode; }
public GamePlayModel(VariantVersion version, GameMode mode) { Tag = version.Variant.Tag; Help = version.Variant.HelpText; if (string.IsNullOrEmpty(Help)) { Help = "No help text has been specified for this variant."; } if (version.Variant.PublicVersionID.HasValue && version.ID == version.Variant.PublicVersionID) { Name = version.Variant.Name; } else { Name = string.Format("{0} v{1}", version.Variant.Name, version.Number); Version = version.Number; } Mode = mode; }
public string CalculateGlobalDirectionDiagram(VariantVersion version) { var directions = new SortedList<string, GlobalDirInfo>(); var board = GetDefinition(version).Board; foreach (XmlNode fromCell in board.SelectNodes("cell")) { // read path attr for X & Y positions var fromCellPath = fromCell.Attributes["path"].Value.Substring(1).Split(space, 3); float fromCellX, fromCellY; if (!float.TryParse(fromCellPath[1], out fromCellY) || fromCellPath[0].Length < 2 || !float.TryParse(fromCellPath[0], out fromCellX)) continue; foreach (XmlNode link in fromCell.ChildNodes) { var dir = link.Attributes["dir"].Value; var toCellName = link.Attributes["to"].Value; var toCell = board.SelectSingleNode(string.Format("cell[@id='{0}']", toCellName)); if (toCell == null) { if (!directions.ContainsKey(dir)) directions[dir] = new GlobalDirInfo(dir, 0); continue; } // read path attr for X & Y positions var toCellPath = toCell.Attributes["path"].Value.Split(space, 3); float toCellX, toCellY; if (!float.TryParse(toCellPath[1], out toCellY) || !float.TryParse(toCellPath[0].Substring(1), out toCellX)) { if (!directions.ContainsKey(dir)) directions[dir] = new GlobalDirInfo(dir, 0); continue; } var dx = toCellX - fromCellX; var dy = toCellY - fromCellY; if (!directions.ContainsKey(dir)) directions[dir] = new GlobalDirInfo(dir) { FirstDX = dx, FirstDY = dy }; var direction = directions[dir]; direction.Num++; direction.DX += dx; direction.DY += dy; } } var svgDoc = new XmlDocument(); svgDoc.AppendChild(svgDoc.CreateElement("svg")); // add a <defs> section containing an arrowhead marker var defs = svgDoc.CreateElement("defs"); defs.InnerXml = @"<marker id=""arrowhead"" viewbox=""0 0 10 10"" refX=""1"" refY=""5"" markerWidth=""6"" markerHeight=""6"" orient=""auto""><path d=""M 0 0 L 10 5 L 0 10 z"" /></marker> <marker id=""arrowhead_from"" viewbox=""0 0 10 10"" refX=""1"" refY=""5"" markerWidth=""6"" markerHeight=""6"" orient=""auto""><path d=""M 0 0 L 10 5 L 0 10 z"" /></marker> <marker id=""arrowhead_to"" viewbox=""0 0 10 10"" refX=""1"" refY=""5"" markerWidth=""6"" markerHeight=""6"" orient=""auto""><path d=""M 0 0 L 10 5 L 0 10 z"" /></marker>"; svgDoc.DocumentElement.AppendChild(defs); var attr = svgDoc.CreateAttribute("xmlns"); attr.Value = "http://www.w3.org/2000/svg"; svgDoc.DocumentElement.Attributes.Append(attr); attr = svgDoc.CreateAttribute("id"); attr.Value = "indicator"; svgDoc.DocumentElement.Attributes.Append(attr); attr = svgDoc.CreateAttribute("viewbox"); attr.Value = "-120 -120 240 240"; svgDoc.DocumentElement.Attributes.Append(attr); // the elements should be written out here sorted by their directions, such that they come out in a clockwise order (this isn't for the diagram itself, but for the edit groups) const float tolerance = 0.01f; foreach(var kvp in directions) { var dir = kvp.Value; if (dir.Num > 1) { dir.DX /= dir.Num; dir.DY /= dir.Num; } if (Math.Abs(dir.DX) < tolerance && Math.Abs(dir.DY) < tolerance) { dir.DX = dir.FirstDX; dir.DY = dir.FirstDY; } } foreach (var dir in directions.Values.OrderBy(dir => dir.Angle)) { Console.WriteLine("{0}, {1}", dir.Name, dir.Angle); var magnitude = (float)Math.Sqrt(dir.DX * dir.DX + dir.DY * dir.DY); dir.DX /= magnitude; dir.DY /= magnitude; var line = svgDoc.CreateElement("line"); svgDoc.DocumentElement.AppendChild(line); attr = svgDoc.CreateAttribute("x1"); attr.Value = (dir.DX * 10).ToString("0.#"); line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("y1"); attr.Value = (dir.DY * 10).ToString("0.#"); line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("x2"); attr.Value = (dir.DX * 100).ToString("0.#"); line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("y2"); attr.Value = (dir.DY * 100).ToString("0.#"); line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("class"); attr.Value = "marker"; line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("dir"); attr.Value = dir.Name; line.Attributes.Append(attr); attr = svgDoc.CreateAttribute("marker-end"); attr.Value = "url(#arrowhead)"; line.Attributes.Append(attr); } return svgDoc.OuterXml; }
public string GetRelativeDirs(VariantVersion version) { StringBuilder sb = new StringBuilder(); var dirRoot = GetDefinition(version).Dirs; if (dirRoot == null) return string.Empty; foreach (XmlNode relativeNode in dirRoot.SelectNodes("relative")) { var relDir = relativeNode.Attributes["name"].Value; foreach(XmlNode link in relativeNode.ChildNodes) sb.AppendFormat(";{0}:{1}:{2}", link.Attributes["from"].Value, relDir, link.Attributes["to"].Value); } return sb.ToString(); }
public XmlNode GetPieceDefinitionXML(VariantVersion version) { var definition = GetDefinition(version); return definition.Pieces; }
public string GetDirectionGroups(VariantVersion version) { var definition = GetDefinition(version); var groups = definition.Dirs.SelectNodes("group"); var sb = new StringBuilder(); foreach (XmlNode groupNode in groups) { sb.Append(outerSep); sb.Append(groupNode.Attributes["name"].Value); foreach (XmlNode dir in groupNode.ChildNodes) { sb.Append(innerSep); sb.Append(dir.Attributes["dir"].Value); } } return sb.ToString(); }
public VariantDefinition GetDefinition(VariantVersion version) { // at some point this should be made to cache definitions, but we have to make sure it updates the cache when they're modified return new VariantDefinition(version); }
public void SaveRelativeDirs(VariantVersion version, string relData) { var definition = GetDefinition(version); var root = definition.Dirs; if (root == null) { root = definition.Dirs = definition.CreateElement("dirs"); } else { // clear existing relative directions var existingDirs = root.SelectNodes("relative"); foreach (XmlNode dir in existingDirs) dir.ParentNode.RemoveChild(dir); } var relativeDirData = new SortedList<string, List<Tuple<string, string>>>(); var relLink = relData.Split(outerSep, StringSplitOptions.RemoveEmptyEntries); foreach (string link in relLink) { var linkParts = link.Split(innerSep, 3); if (linkParts.Length != 3) continue; string from = linkParts[0]; string relDir = linkParts[1]; string to = linkParts[2]; List<Tuple<string, string>> linksForThisDir; if (!relativeDirData.TryGetValue(relDir, out linksForThisDir)) { linksForThisDir = new List<Tuple<string, string>>(); relativeDirData.Add(relDir, linksForThisDir); } linksForThisDir.Add(new Tuple<string, string>(from, to)); } foreach (var kvp in relativeDirData) { var relDirNode = definition.CreateElement("relative"); relDirNode.Attributes.Append(definition.CreateAttribute("name", kvp.Key)); foreach(var link in kvp.Value) { var linkNode = definition.CreateElement("link"); linkNode.Attributes.Append(definition.CreateAttribute("from", link.Item1)); linkNode.Attributes.Append(definition.CreateAttribute("to", link.Item2)); relDirNode.AppendChild(linkNode); } root.PrependChild(relDirNode); } definition.Dirs = root; version.LastModified = DateTime.Now; Entities.SaveChanges(); }
public bool SaveBoardData(VariantVersion version, string boardSVG, string cellLinks) { XmlDocument svgDoc = new XmlDocument(); try { svgDoc.LoadXml(boardSVG); } catch { return false; } var definition = GetDefinition(version); var board = definition.CreateElement("board"); var viewBox = definition.CreateAttribute("viewBox"); viewBox.Value = svgDoc.DocumentElement.HasAttribute("viewBox") ? svgDoc.DocumentElement.Attributes["viewBox"].Value : definition.Board.Attributes["viewBox"].Value; board.Attributes.Append(viewBox); foreach (XmlNode node in svgDoc.DocumentElement.ChildNodes) { if (node.Name == "path") SaveCellFromSVG(node, board); else if (node.Name == "line") SaveLineFromSVG(node, board); } SaveLinkData(definition, board, cellLinks); definition.Board = board; version.LastModified = DateTime.Now; Entities.SaveChanges(); return true; }
public void SaveDirectionGroups(VariantVersion version, string groupData) { var definition = GetDefinition(version); var root = definition.Dirs; if (root == null) { root = definition.Dirs = definition.CreateElement("dirs"); } else { // clear existing direction groups var existingGroups = root.SelectNodes("group"); foreach (XmlNode group in existingGroups) group.ParentNode.RemoveChild(group); } var groups = groupData.Split(outerSep, StringSplitOptions.RemoveEmptyEntries); foreach (string group in groups) { var groupParts = group.Split(innerSep); var groupNode = definition.CreateElement("group"); groupNode.Attributes.Append(definition.CreateAttribute("name", groupParts[0])); for (int i = 1; i < groupParts.Length; i++) { var linkNode = definition.CreateElement("include"); linkNode.Attributes.Append(definition.CreateAttribute("dir", groupParts[i])); groupNode.AppendChild(linkNode); } root.AppendChild(groupNode); } definition.Dirs = root; version.LastModified = DateTime.Now; Entities.SaveChanges(); }
public IEnumerable<string> ListGlobalDirections(VariantVersion version) { SortedSet<string> directions = new SortedSet<string>(); var board = GetDefinition(version).Board; foreach (XmlNode fromCell in board.SelectNodes("cell")) foreach (XmlNode link in fromCell.ChildNodes) { var dir = link.Attributes["dir"].Value; if (!directions.Contains(dir)) directions.Add(dir); } return directions; }
public RawModel(VariantVersion version) { VariantName = version.Variant.Name; XmlData = version.Definition; ThisPage = "Raw xml"; }
public VariantSelectionModel(VariantVersion version, string customName, bool isPrivate) : this(version) { Name = customName; IsPrivate = isPrivate; }
public IEnumerable<string> ListRelativeDirections(VariantVersion version) { SortedSet<string> directions = new SortedSet<string>(); var dirRoot = GetDefinition(version).Dirs; if (dirRoot == null) return new string[0]; foreach (XmlNode relativeNode in dirRoot.SelectNodes("relative")) { var dir = relativeNode.Attributes["name"].Value; if (!directions.Contains(dir)) directions.Add(dir); } return directions; }
public static string DescribeVersion(VariantVersion version) { return string.Format("v{0} @ {1}", version.Number, version.LastModified.ToString("d")); }
public void SaveCellReferenceChanges(VariantVersion version, string renameData) { var definition = GetDefinition(version); var board = definition.Board; var renames = renameData.Split(outerSep, StringSplitOptions.RemoveEmptyEntries); foreach (var rename in renames) { var parts = rename.Split(innerSep); if (parts.Length != 2) continue; var from = parts[0]; var to = parts[1]; var alreadyExists = board.SelectSingleNode(string.Format("cell[@id='{0}']", to)); if (alreadyExists != null) continue; // find the "from" cell, and change its ID to the "to" value. var cell = board.SelectSingleNode(string.Format("cell[@id='{0}']", from)); if (cell == null) continue; cell.Attributes["id"].Value = to; // do the same for ALL links to this cell var links = board.SelectNodes(string.Format("cell/link[@to='{0}']", from)); foreach (XmlNode link in links) link.Attributes["to"].Value = to; } definition.Board = board; version.LastModified = DateTime.Now; Entities.SaveChanges(); }
public void SaveLinkData(VariantVersion version, string linkData) { var definition = GetDefinition(version); var board = definition.Board; SaveLinkData(definition, board, linkData); definition.Board = board; version.LastModified = DateTime.Now; Entities.SaveChanges(); }
public XmlDocument GetBoardSVG(VariantVersion version, bool addArrowheadDef = false, bool showCellRefs = false) { var board = GetDefinition(version).Board; XmlDocument svgDoc = new XmlDocument(); svgDoc.AppendChild(svgDoc.CreateElement("svg")); if (addArrowheadDef) { // add a <defs> section containing an arrowhead marker var defs = svgDoc.CreateElement("defs"); defs.InnerXml = @"<marker id=""arrowhead"" viewbox=""0 0 10 10"" refX=""1"" refY=""5"" markerWidth=""6"" markerHeight=""6"" orient=""auto""><path d=""M 0 0 L 10 5 L 0 10 z"" /></marker>"; svgDoc.DocumentElement.AppendChild(defs); } var attr = svgDoc.CreateAttribute("xmlns"); attr.Value = "http://www.w3.org/2000/svg"; svgDoc.DocumentElement.Attributes.Append(attr); attr = svgDoc.CreateAttribute("id"); attr.Value = "render"; svgDoc.DocumentElement.Attributes.Append(attr); attr = svgDoc.CreateAttribute("viewBox"); attr.Value = board.Attributes["viewBox"].Value; svgDoc.DocumentElement.Attributes.Append(attr); foreach (XmlNode node in board.ChildNodes) { if (node.Name == "cell") WriteCellToSVG(node, svgDoc); else if (node.Name == "line") WriteLineToSVG(node, svgDoc); } if (showCellRefs) // done last, so that references appear on top of lines foreach (XmlNode node in board.SelectNodes("cell")) WriteCellRefToSVG(node, svgDoc); return svgDoc; }
public string GetCellLinks(VariantVersion version) { var board = GetDefinition(version).Board; var sb = new StringBuilder(); foreach (XmlNode cell in board.SelectNodes("cell")) foreach (XmlNode link in cell.SelectNodes("link")) sb.AppendFormat(";{0}:{1}:{2}", cell.Attributes["id"].Value, link.Attributes["dir"].Value, link.Attributes["to"].Value); return sb.ToString(); }
public ActionResult New([Bind(Include = "Name,NumPlayers,Description,HelpText")] VariantEditModel model) { if (!ModelState.IsValid) return RedirectToAction("New"); UserService users = GetService<UserService>(); VariantService variants = GetService<VariantService>(); var user = users.GetByName(User.Identity.Name); var variant = new Variant(); variant.CreatedByID = user.ID; variant.Description = model.Description ?? string.Empty; variant.HelpText = DataService.StripTags(model.HelpText ?? string.Empty); variant.PlayerCount = (byte)model.NumPlayers; if (!ValidateName(model, variant)) return View(model); var version = new VariantVersion(); version.Number = 1; version.LastModified = DateTime.Now; version.Variant = variant; version.Definition = string.Empty; Entities().Variants.Add(variant); Entities().VariantVersions.Add(version); Entities().SaveChanges(); return RedirectToAction("Shape", "Designer", new { version.ID }); }
public bool IsAllowedToPlay(VariantVersion version, string userName) { return (version.Variant.PublicVersionID.HasValue && version.Variant.PublicVersionID == version.ID) || version.Variant.CreatedBy.Name == userName; }