private ShPlayer _Player; //reference to Player in SheepGame.Players //constructor public ShAnswer(ShGroup ref_group, ShPlayer ref_player, string new_text) { this.Text = new_text; this.AnswerBonus = 0; this._Group = ref_group; this._Player = ref_player; }
//show right-click menu //set Tag of RCM_group or RCM_answer to the clicked node private void treeView1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right && treeView1.GetNodeAt(e.Location) != null && treeView1.GetNodeAt(e.Location).Tag != null) { TreeNode clicked_node = treeView1.GetNodeAt(e.Location); treeView1.SelectedNode = clicked_node; if (clicked_node.Tag.GetType() == typeof(ShGroup)) { ShGroup grp = (ShGroup)clicked_node.Tag; RCM_group.Tag = clicked_node; RCM_group_correct.Text = "Mark " + ShGame.GetCorrectText(curScoreMethod, !grp.Correct); RCM_group.Show(treeView1, e.Location); } else if (clicked_node.Tag.GetType() == typeof(ShAnswer)) { RCM_answer.Tag = clicked_node; RCM_answer.Show(treeView1, e.Location); } } }
//Constructor2 //initialize with an array of questions, players, answers public ShGame(string[] new_questions, string[] new_players, string[,] new_answers) { if (new_answers.GetLength(0) != new_questions.Length || new_answers.GetLength(1) != new_players.Length) { throw new Exception("Answer list must be size [num questions, num players]"); } Questions = new List <ShQuestion>(new_questions.Length); Players = new List <ShPlayer>(new_players.Length); Questions.AddRange(new_questions.Select(txt => new ShQuestion(this, txt))); Players.AddRange(new_players.Select(txt => new ShPlayer(this, txt))); for (int iques = 0; iques < new_questions.Length; iques++) { for (int iplayer = 0; iplayer < new_players.Length; iplayer++) { ShGroup new_group = new ShGroup(Questions[iques], new_answers[iques, iplayer]); Questions[iques].Groups.Add(new_group); ShAnswer new_answer = new ShAnswer(new_group, Players[iplayer], new_answers[iques, iplayer]); new_group.Answers.Add(new_answer); Players[iplayer].Answers.Add(new_answer); } } }
public ShGroup StartNewGroup(string new_text) { ShGroup newGrp = new ShGroup(this, new_text); this.Groups.Add(newGrp); return(newGrp); }
//nicely add a player, using new_answers public ShPlayer NiceAddPlayer(string new_name, string[] new_answers, decimal start_score = 0) { ShPlayer newP = new ShPlayer(this, new_name, start_score); Players.Add(newP); for (int iques = 0; iques < Questions.Count; iques++) { //get text for new answers string newAnsTxt = "(blank)"; if (iques < new_answers.Length) { if (new_answers[iques] != "") { newAnsTxt = new_answers[iques]; } } ShGroup newG = new ShGroup(Questions[iques], newAnsTxt); Questions[iques].Groups.Add(newG); ShAnswer newA = new ShAnswer(newG, newP, newAnsTxt); newG.Answers.Add(newA); newP.Answers.Add(newA); } return(newP); }
//change group of answer //use GroupSync() after to remove empty groups public void ChangeGroup(ShGroup ref_group) { if (ref_group == this._Group) { return; } if (this._Group.Question != ref_group.Question) { throw new Exception("Moving an answer to a group in a different question."); } ShGroup oldGroup = this._Group; //add to new group this._Group = ref_group; ref_group.Answers.Add(this); //remove it from old group oldGroup.Answers.Remove(this); if (oldGroup.Answers.Count == 0) { //delete old group if it's empty oldGroup.Question.Groups.Remove(oldGroup); } }
//right click menu - mark group as (in)correct/(in)valid private void RCM_group_correct_Click(object sender, EventArgs e) { TreeNode clicked_node = RCM_group.Tag as TreeNode; if (clicked_node == null) { return; } ShGroup grp = clicked_node.Tag as ShGroup; if (grp == null) { return; } if (grp.Correct) { grp.Correct = false; } else { grp.Correct = true; } sheep_modified = true; SetTextForAllTreenodes(); }
//update text on all treenode items private void SetTextForAllTreenodes() { if (treeView1.Nodes.Count == 0) { return; } int i = 0; foreach (TreeNode grpNode in treeView1.Nodes) { if (grpNode.Tag == null) { continue; } if (grpNode.Tag.GetType() == typeof(ShGroup)) { ShGroup grp = (ShGroup)grpNode.Tag; grpNode.Text = TextForTreeNode(grp); foreach (TreeNode ansNode in grpNode.Nodes) { if (ansNode.Tag.GetType() == typeof(ShAnswer)) { ansNode.Text = TextForTreeNode((ShAnswer)ansNode.Tag); ansNode.ForeColor = treeView1.ForeColor; } } if (i % 2 == 0) { grpNode.BackColor = Color.FromArgb(245, 245, 245); } else { grpNode.BackColor = Color.FromArgb(230, 230, 230); } if (grp.Correct) { grpNode.ForeColor = Color.Blue; } else { grpNode.ForeColor = Color.DarkRed; } } i++; } }
//nicely add a player, setting answers blank public ShPlayer NiceAddPlayer(string new_name) { ShPlayer newP = new ShPlayer(this, new_name); Players.Add(newP); for (int iques = 0; iques < Questions.Count; iques++) { ShGroup newG = new ShGroup(Questions[iques], "(blank)"); Questions[iques].Groups.Add(newG); ShAnswer newA = new ShAnswer(newG, newP, "(blank)"); newG.Answers.Add(newA); newP.Answers.Add(newA); } return(newP); }
//creates new group and moves answer to it public void StartNewGroup() { ShGroup oldGroup = this._Group; ShGroup newGroup = new ShGroup(_Group.Question, Text); oldGroup.Question.Groups.Add(newGroup); this._Group = newGroup; newGroup.Answers.Add(this); oldGroup.Answers.Remove(this); if (oldGroup.Answers.Count == 0) { //delete old group if it's empty oldGroup.Question.Groups.Remove(oldGroup); } }
//moves all answers to ref_group and deletes itself public void MergeToGroup(ShGroup ref_group) { if (ref_group == this) { // throw new Exception("Trying to merge a group to itself"); return; } while (Answers.Count != 0) { Answers.First().ChangeGroup(ref_group); } _Question.Groups.Remove(this); }
//nicely add a question, giving each player a blank answer //and making one group public ShQuestion NiceAddQuestion(string qtxt) { ShQuestion newQ = new ShQuestion(this, qtxt); Questions.Add(newQ); if (Players.Count > 0) { ShGroup newG = new ShGroup(newQ, "(blank)"); newQ.Groups.Add(newG); foreach (ShPlayer ply in Players) { ShAnswer newA = new ShAnswer(newG, ply, "(blank)"); ply.Answers.Add(newA); newG.Answers.Add(newA); } } return(newQ); }
public int Compare(object x, object y) { TreeNode tx = x as TreeNode; TreeNode ty = y as TreeNode; if (tx.Tag == null || ty.Tag == null) { return(0); } if (tx.Tag.GetType() == typeof(ShGroup) && ty.Tag.GetType() == typeof(ShGroup)) { ShGroup gx = (ShGroup)tx.Tag; ShGroup gy = (ShGroup)ty.Tag; return(string.Compare(gx.Text, gy.Text)); } else if (tx.Tag.GetType() == typeof(ShAnswer) && ty.Tag.GetType() == typeof(ShAnswer)) { int temp = string.Compare( ((ShAnswer)tx.Tag).Text, ((ShAnswer)ty.Tag).Text, true); if (temp != 0) { return(temp); } else { return(string.Compare( ((ShAnswer)tx.Tag).Player.Name, ((ShAnswer)ty.Tag).Player.Name, true)); } } else { return(0); } }
//returns text that should be displayed on this treenode private string TextForTreeNode(ShGroup grp) { if (grp.Answers.Count == 0) { return(grp.Text); } string scoreString = ""; try { if (curScoreMethod == ShScoringMethod.Manual) { scoreString = "[" + grp.GroupBonus + "]"; } else { string bonus_text = ""; if (grp.GroupBonus > 0) { bonus_text = " + " + grp.GroupBonus.ToString(); } if (grp.GroupBonus < 0) { bonus_text = " - " + (-grp.GroupBonus).ToString(); } scoreString = "[" + grp.Question.Scores(false) [grp.Answers[0].Player].ToString() + bonus_text + "]"; } } catch { scoreString = "ERROR"; } return(grp.Text + " - " + (grp.Correct ? "" : ShGame.GetCorrectText(curScoreMethod, grp.Correct).ToUpper() + " - ") + scoreString); }
//right click menu - set bonus score for a group private void RCM_group_bonus_Click(object sender, EventArgs e) { TreeNode clicked_node = RCM_group.Tag as TreeNode; if (clicked_node == null) { return; } ShGroup grp = clicked_node.Tag as ShGroup; if (grp == null) { return; } InputText IP = new InputText(); IP.Text = "Bonus Score"; IP.label1.Text = "Enter bonus score for " + grp.Text + ":"; IP.textBox1.Text = grp.GroupBonus.ToString(); IP.StartPosition = FormStartPosition.CenterParent; IP.ShowDialog(); if (IP.DialogResult == DialogResult.OK) { if (IP.textBox1.Text.Trim() == "") { grp.GroupBonus = 0; } try { grp.GroupBonus = Convert.ToInt32(IP.textBox1.Text); } catch { } sheep_modified = true; SetTextForAllTreenodes(); } }
//right click menu - create a new group with this answer private void RCM_move_to_new_group_Click(object sender, EventArgs e) { TreeNode clicked_node = RCM_answer.Tag as TreeNode; if (clicked_node == null) { return; } ShAnswer ans = clicked_node.Tag as ShAnswer; if (ans == null) { return; } ShGroup newGroup = ans.Group.Question.StartNewGroup(ans.Text); ans.ChangeGroup(newGroup); TreeNode prevParent = clicked_node.Parent; TreeNode newParent = treeView1.Nodes.Add("b"); newParent.Tag = newGroup; prevParent.Nodes.Remove(clicked_node); newParent.Nodes.Add(clicked_node); newParent.Expand(); //if prevParent is empty, delete it if (prevParent.Nodes.Count == 0) { prevParent.Remove(); } sheep_modified = true; SetTextForAllTreenodes(); }
//read data from xmlreader public void ReadFromXML(XmlReader xr) { Questions.Clear(); Players.Clear(); Method = ShMethod.Sheep; Rounding = ShRoundingType.None; #region xrread while (xr.Read()) { if (xr.IsStartElement()) { switch (xr.Name) { case "ScoringMethod": Method = (ShMethod)Enum.Parse(typeof(ShMethod), xr.ReadElementString()); break; case "Rounding": Rounding = (ShRoundingType)Enum.Parse(typeof(ShRoundingType), xr.ReadElementString()); break; case "Question": int qindex = Convert.ToInt32(xr["GameIndex"]); while (Questions.Count < qindex + 1) { Questions.Add(new ShQuestion(this, "(blank)")); } Questions[qindex].Text = xr.ReadElementString(); break; case "Player": int pindex = Convert.ToInt32(xr["GameIndex"]); decimal start_score = Convert.ToDecimal(xr["StartScore"]); while (Players.Count < pindex + 1) { Players.Add(new ShPlayer(this, "(blank)", start_score)); } Players[pindex].Name = xr.ReadElementString(); break; case "Group": //assuming that question and player have already been //completely read in as they should be at the start //of the xml file int group_q_index = Convert.ToInt32(xr["QuestionIndex"]); bool tempcorrect = Convert.ToBoolean(xr["Correct"]); decimal tempgroupbonus = Convert.ToDecimal(xr["GroupBonus"]); var tempgroupbonustype = (ShBonusType)Enum.Parse(typeof(ShBonusType), xr["BonusType"]); ShGroup newGroup = new ShGroup(this.Questions[group_q_index], ""); newGroup.Correct = tempcorrect; newGroup.GroupBonus = tempgroupbonus; newGroup.BonusType = tempgroupbonustype; Questions[group_q_index].Groups.Add(newGroup); XmlReader subxr = xr.ReadSubtree(); while (subxr.Read()) { if (subxr.IsStartElement()) { switch (subxr.Name) { case "Text": newGroup.Text = subxr.ReadElementString(); break; case "Answer": int ans_p_index = Convert.ToInt32(subxr["PlayerIndex"]); decimal tempansbonus = Convert.ToDecimal(subxr["AnswerBonus"]); var tempansbonustype = (ShBonusType)Enum.Parse(typeof(ShBonusType), xr["BonusType"]); string anstext = xr.ReadElementString(); ShAnswer newAns = new ShAnswer(newGroup, Players[ans_p_index], anstext); newAns.AnswerBonus = tempansbonus; newAns.BonusType = tempansbonustype; newGroup.Answers.Add(newAns); Players[ans_p_index].Answers.Add(newAns); break; } } } break; } } } #endregion }
//main drag/drop function private void treeView1_DragDrop(object sender, DragEventArgs e) { //stop sorting while dragging treeView1.TreeViewNodeSorter = null; Point cp = treeView1.PointToClient(new Point(e.X, e.Y)); TreeNode destNode = treeView1.GetNodeAt(cp); //don't continue if not a valid node if (!e.Data.GetDataPresent(typeof(TreeNode))) { return; } // treeView1.BeginUpdate(); TreeNode movingNode = (TreeNode)e.Data.GetData(typeof(TreeNode)); TreeNode prevParent, newParent; ShQuestion curQuestion = sg.Questions[cur_q_index]; //different code depending on what type of thing we're dragging/dragging to if (movingNode.Tag.GetType() == typeof(ShAnswer) && destNode.Tag.GetType() == typeof(ShAnswer)) { //moving an answer to another answer ShAnswer ansToMove = (ShAnswer)movingNode.Tag; ShAnswer destAnswer = (ShAnswer)destNode.Tag; ansToMove.ChangeGroup(destAnswer.Group); prevParent = movingNode.Parent; newParent = destNode.Parent; prevParent.Nodes.Remove(movingNode); newParent.Nodes.Add(movingNode); } else if (movingNode.Tag.GetType() == typeof(ShAnswer) && destNode.Tag.GetType() == typeof(ShGroup)) { //moving an answer to another group ShAnswer ansToMove = (ShAnswer)movingNode.Tag; ShGroup destGroup = (ShGroup)destNode.Tag; ansToMove.ChangeGroup(destGroup); prevParent = movingNode.Parent; newParent = destNode; prevParent.Nodes.Remove(movingNode); newParent.Nodes.Add(movingNode); } else if (movingNode.Tag.GetType() == typeof(ShGroup) && destNode.Tag.GetType() == typeof(ShAnswer)) { //moving a group to an answer ShGroup grpToMove = (ShGroup)movingNode.Tag; ShAnswer destAnswer = (ShAnswer)destNode.Tag; grpToMove.MergeToGroup(destAnswer.Group); prevParent = movingNode; newParent = destNode.Parent; List <TreeNode> ansNodes = new List <TreeNode>(prevParent.Nodes.Cast <TreeNode>()); foreach (TreeNode nod in ansNodes) { prevParent.Nodes.Remove(nod); newParent.Nodes.Add(nod); } } else if (movingNode.Tag.GetType() == typeof(ShGroup) && destNode.Tag.GetType() == typeof(ShGroup)) { //moving a group to a group ShGroup grpToMove = (ShGroup)movingNode.Tag; ShGroup destGroup = (ShGroup)destNode.Tag; grpToMove.MergeToGroup(destGroup); prevParent = movingNode; newParent = destNode; List <TreeNode> ansNodes = new List <TreeNode>(prevParent.Nodes.Cast <TreeNode>()); foreach (TreeNode nod in ansNodes) { prevParent.Nodes.Remove(nod); newParent.Nodes.Add(nod); } } else { treeView1.EndUpdate(); return; } //if prevParent is empty, delete it if (prevParent.Nodes.Count == 0) { prevParent.Remove(); } SetTextForAllTreenodes(); sheep_modified = true; treeView1.EndUpdate(); }