From 1c1fc2fe6c36c1c5283807300f3c511b8a5dc621 Mon Sep 17 00:00:00 2001 From: Rishabh Gupta Date: Fri, 1 Feb 2019 14:56:11 +0530 Subject: [PATCH 1/3] tic tac toe --- index.html | 174 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 index.html diff --git a/index.html b/index.html new file mode 100644 index 0000000..0a5e56d --- /dev/null +++ b/index.html @@ -0,0 +1,174 @@ + + + + + + +
+
Player 1
+ +
+ + + + + + + + + + + + + + + + + + + +
+
+
+ + + \ No newline at end of file From 2103769d8c95984f212ced5dad530401ae505401 Mon Sep 17 00:00:00 2001 From: Rishabh Gupta Date: Sat, 9 Feb 2019 19:13:36 +0530 Subject: [PATCH 2/3] Improved UI and included draw case --- index.html | 204 +++++++++++++++++++++++++---------------------------- index.js | 150 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 245 insertions(+), 109 deletions(-) create mode 100644 index.js diff --git a/index.html b/index.html index 0a5e56d..5c56d92 100644 --- a/index.html +++ b/index.html @@ -1,15 +1,19 @@ +
+
+
+
+
Player 1
+ +
+
+
+
+
+
Player 2
+ +
+
+
-
Player 1
+
Player 1
@@ -63,112 +152,9 @@
+
- - }) - \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..4bd10c4 --- /dev/null +++ b/index.js @@ -0,0 +1,150 @@ +var c = [ 0,0,0,0,0,0,0,0,0]; +var gameover = 0; +function getPlayerName(x){ + return x == 1 ? 'Player 1' : 'Player 2'; +} + +function changeMessage(message){ + $('.message').text(message); +} + +function getRandomChance(){ + + return Math.floor(Math.random()*2) == 0?-1:1; +} +var chance = getRandomChance(); +changeUI(); + +function changeUI(){ + + $('.player').removeClass('player-highlighted'); + $('.player').eq(chance==1?0:1).addClass('player-highlighted'); + changeMessage(getPlayerName(chance) + " Chance"); + +} +function changeChance(){ + if(chance == 1) + chance = -1; + else + chance = 1; + + changeUI(); +} + +function check() +{ + + var i; + //Check All rows + var sum =0; + for( i= 0;i<7;i=i+3) + { sum = 0; + for( j=i;j Date: Sat, 9 Feb 2019 19:28:56 +0530 Subject: [PATCH 3/3] Added Backend Improve UI --- .gitignore | 5 + DatabaseSQLCommands.txt | 9 + TicTacToe/TicTacToe.sln | 22 + TicTacToe/TicTacToe/App_Start/WebApiConfig.cs | 24 + .../TicTacToe/ApplicationInsights.config | 84 ++ .../TicTacToe/Controllers/LoginController.cs | 43 + .../TicTacToe/Controllers/UsersController.cs | 174 +++++ TicTacToe/TicTacToe/Global.asax | 1 + TicTacToe/TicTacToe/Global.asax.cs | 22 + TicTacToe/TicTacToe/Models/Game.Context.cs | 30 + TicTacToe/TicTacToe/Models/Game.Context.tt | 636 +++++++++++++++ TicTacToe/TicTacToe/Models/Game.Designer.cs | 10 + TicTacToe/TicTacToe/Models/Game.cs | 9 + TicTacToe/TicTacToe/Models/Game.edmx | 75 ++ TicTacToe/TicTacToe/Models/Game.edmx.diagram | 12 + TicTacToe/TicTacToe/Models/Game.tt | 733 ++++++++++++++++++ TicTacToe/TicTacToe/Models/User.cs | 22 + .../TicTacToe/Properties/AssemblyInfo.cs | 35 + TicTacToe/TicTacToe/TicTacToe.csproj | 240 ++++++ TicTacToe/TicTacToe/TicTacToe.csproj.user | 38 + TicTacToe/TicTacToe/Web.Debug.config | 30 + TicTacToe/TicTacToe/Web.Release.config | 31 + TicTacToe/TicTacToe/Web.config | 61 ++ TicTacToe/TicTacToe/packages.config | 21 + const.js | 1 + databaseschema.PNG | Bin 0 -> 5043 bytes ...baseline_power_settings_new_white_24dp.png | Bin 0 -> 277 bytes img/crackers.gif | Bin 0 -> 138598 bytes index.html | 157 ++-- index.js | 201 ++++- style.css | 153 ++++ 31 files changed, 2758 insertions(+), 121 deletions(-) create mode 100644 .gitignore create mode 100644 DatabaseSQLCommands.txt create mode 100644 TicTacToe/TicTacToe.sln create mode 100644 TicTacToe/TicTacToe/App_Start/WebApiConfig.cs create mode 100644 TicTacToe/TicTacToe/ApplicationInsights.config create mode 100644 TicTacToe/TicTacToe/Controllers/LoginController.cs create mode 100644 TicTacToe/TicTacToe/Controllers/UsersController.cs create mode 100644 TicTacToe/TicTacToe/Global.asax create mode 100644 TicTacToe/TicTacToe/Global.asax.cs create mode 100644 TicTacToe/TicTacToe/Models/Game.Context.cs create mode 100644 TicTacToe/TicTacToe/Models/Game.Context.tt create mode 100644 TicTacToe/TicTacToe/Models/Game.Designer.cs create mode 100644 TicTacToe/TicTacToe/Models/Game.cs create mode 100644 TicTacToe/TicTacToe/Models/Game.edmx create mode 100644 TicTacToe/TicTacToe/Models/Game.edmx.diagram create mode 100644 TicTacToe/TicTacToe/Models/Game.tt create mode 100644 TicTacToe/TicTacToe/Models/User.cs create mode 100644 TicTacToe/TicTacToe/Properties/AssemblyInfo.cs create mode 100644 TicTacToe/TicTacToe/TicTacToe.csproj create mode 100644 TicTacToe/TicTacToe/TicTacToe.csproj.user create mode 100644 TicTacToe/TicTacToe/Web.Debug.config create mode 100644 TicTacToe/TicTacToe/Web.Release.config create mode 100644 TicTacToe/TicTacToe/Web.config create mode 100644 TicTacToe/TicTacToe/packages.config create mode 100644 const.js create mode 100644 databaseschema.PNG create mode 100644 img/baseline_power_settings_new_white_24dp.png create mode 100644 img/crackers.gif create mode 100644 style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0dbca8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +TicTacToe/.vs +TicTacToe/packages +TicTacToe/TicTacToe/bin +TicTacToe/TicTacToe/obj +TicTacToe/TicTacToe/scripts \ No newline at end of file diff --git a/DatabaseSQLCommands.txt b/DatabaseSQLCommands.txt new file mode 100644 index 0000000..e7c9eed --- /dev/null +++ b/DatabaseSQLCommands.txt @@ -0,0 +1,9 @@ +CREATE DATABASE Game; +CREATE TABLE [Users]( +[Id] INT PRIMARY KEY IDENTITY(1,1), +[UserName] VARCHAR(50) UNIQUE NOT NULL, +[Password] VARCHAR(15), +[Points] INT, +) +INSERT INTO Users VALUES('rakesh','password',0); +INSERT INTO Users VALUES('aman','password',0); \ No newline at end of file diff --git a/TicTacToe/TicTacToe.sln b/TicTacToe/TicTacToe.sln new file mode 100644 index 0000000..621c6f0 --- /dev/null +++ b/TicTacToe/TicTacToe.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 14 for Web +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TicTacToe", "TicTacToe\TicTacToe.csproj", "{8C062E7F-600F-444B-9FE9-396ED8247AEC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C062E7F-600F-444B-9FE9-396ED8247AEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C062E7F-600F-444B-9FE9-396ED8247AEC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C062E7F-600F-444B-9FE9-396ED8247AEC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C062E7F-600F-444B-9FE9-396ED8247AEC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/TicTacToe/TicTacToe/App_Start/WebApiConfig.cs b/TicTacToe/TicTacToe/App_Start/WebApiConfig.cs new file mode 100644 index 0000000..4b7cefc --- /dev/null +++ b/TicTacToe/TicTacToe/App_Start/WebApiConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using System.Web.Http.Cors; + +namespace TicTacToe +{ + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + var cors = new EnableCorsAttribute("*", "*", "*"); + config.EnableCors(cors); + config.MapHttpAttributeRoutes(); + + config.Routes.MapHttpRoute( + name: "DefaultApi", + routeTemplate: "api/{controller}/{id}", + defaults: new { id = RouteParameter.Optional } + ); + } + } +} diff --git a/TicTacToe/TicTacToe/ApplicationInsights.config b/TicTacToe/TicTacToe/ApplicationInsights.config new file mode 100644 index 0000000..ee9ea3c --- /dev/null +++ b/TicTacToe/TicTacToe/ApplicationInsights.config @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + System.Web.Handlers.TransferRequestHandler + Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler + System.Web.StaticFileHandler + System.Web.Handlers.AssemblyResourceLoader + System.Web.Optimization.BundleHandler + System.Web.Script.Services.ScriptHandlerFactory + System.Web.Handlers.TraceHandler + System.Web.Services.Discovery.DiscoveryRequestHandler + System.Web.HttpDebugHandler + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Controllers/LoginController.cs b/TicTacToe/TicTacToe/Controllers/LoginController.cs new file mode 100644 index 0000000..41e2aa2 --- /dev/null +++ b/TicTacToe/TicTacToe/Controllers/LoginController.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http; +using System.Web.Http.Description; +using TicTacToe.Models; + +namespace TicTacToe.Controllers +{ + public class LoginController : ApiController + { + private GameEntities db = new GameEntities(); + + [HttpPost] + [Route("api/login")] + public IHttpActionResult GetUser(JObject jdata) + { + String username; + String password; + dynamic data = jdata; + try + { + username = data.UserName.ToObject(); + password = data.Password.ToObject(); + } + catch(Exception) + { + return BadRequest(); + } + User user = db.Users.Where(u => u.UserName == username && u.Password == password).FirstOrDefault(); + + if (user == null) + { + return NotFound(); + } + + return Json( new { username = user.UserName ,points = user.Points}); + } + } +} diff --git a/TicTacToe/TicTacToe/Controllers/UsersController.cs b/TicTacToe/TicTacToe/Controllers/UsersController.cs new file mode 100644 index 0000000..d7c6e6b --- /dev/null +++ b/TicTacToe/TicTacToe/Controllers/UsersController.cs @@ -0,0 +1,174 @@ +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.Entity; +using System.Data.Entity.Infrastructure; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http; +using System.Web.Http.Description; +using TicTacToe.Models; + +namespace TicTacToe.Controllers +{ + public class UsersController : ApiController + { + private GameEntities db = new GameEntities(); + + // GET: api/Users + public IQueryable GetUsers() + { + return db.Users; + } + + // GET: api/Users/5 + [ResponseType(typeof(User))] + public IHttpActionResult GetUser(int id) + { + User user = db.Users.Find(id); + if (user == null) + { + return NotFound(); + } + + return Ok(user); + } + // GET: api/Users/username/Points + [HttpGet] + [Route("api/Users/{username}/Points")] + public IHttpActionResult GetPoints(string username) + { + User user = db.Users.Where(u => u.UserName == username).FirstOrDefault(); + if (user == null) + { + return NotFound(); + } + + return Json(new { status = 1, username = user.UserName, points = user.Points }); + } + + + // PUT: api/Users/5 + [ResponseType(typeof(void))] + public IHttpActionResult PutUser(int id, User user) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + if (id != user.Id) + { + return BadRequest(); + } + + db.Entry(user).State = EntityState.Modified; + + try + { + db.SaveChanges(); + } + catch (DbUpdateConcurrencyException) + { + if (!UserExists(id)) + { + return NotFound(); + } + else + { + throw; + } + } + + return StatusCode(HttpStatusCode.NoContent); + } + + // POST: api/Users + [ResponseType(typeof(User))] + public IHttpActionResult PostUser(User user) + { + if (!ModelState.IsValid) + { + return BadRequest(ModelState); + } + + db.Users.Add(user); + db.SaveChanges(); + + return CreatedAtRoute("DefaultApi", new { id = user.Id }, user); + } + + // DELETE: api/Users/5 + [ResponseType(typeof(User))] + public IHttpActionResult DeleteUser(int id) + { + User user = db.Users.Find(id); + if (user == null) + { + return NotFound(); + } + + db.Users.Remove(user); + db.SaveChanges(); + + return Ok(user); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + db.Dispose(); + } + base.Dispose(disposing); + } + + private bool UserExists(int id) + { + return db.Users.Count(e => e.Id == id) > 0; + } + + // PATCH: api/Users + [HttpPatch] + [Route("api/Users")] + public IHttpActionResult PatchUser(JObject jdata) + { + String username; + int points ; + dynamic data = jdata; + try + { + username = data.UserName.ToObject(); + points = (int)data.Points; + } + catch (Exception e) + { + return BadRequest(); + } + User user = db.Users.Where(u => u.UserName == username).FirstOrDefault(); + + if (user == null) + { + return NotFound(); + } + else + { + user.Points = points; + db.Entry(user).State = EntityState.Modified; + try + { + db.SaveChanges(); + } + catch (DbUpdateConcurrencyException e) + { + return Json(new { status = 0, message = e.Message }); + } + + } + + return Json(new { status = 1, username = user.UserName, points = user.Points }); + } + } +} \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Global.asax b/TicTacToe/TicTacToe/Global.asax new file mode 100644 index 0000000..d39af86 --- /dev/null +++ b/TicTacToe/TicTacToe/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="TicTacToe.WebApiApplication" Language="C#" %> diff --git a/TicTacToe/TicTacToe/Global.asax.cs b/TicTacToe/TicTacToe/Global.asax.cs new file mode 100644 index 0000000..3145a31 --- /dev/null +++ b/TicTacToe/TicTacToe/Global.asax.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Http; +using System.Web.Routing; + +namespace TicTacToe +{ + public class WebApiApplication : System.Web.HttpApplication + { + protected void Application_Start() + { + GlobalConfiguration.Configure(WebApiConfig.Register); + HttpConfiguration config = GlobalConfiguration.Configuration; + + config.Formatters.JsonFormatter + .SerializerSettings + .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; + } + } +} \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/Game.Context.cs b/TicTacToe/TicTacToe/Models/Game.Context.cs new file mode 100644 index 0000000..ff431fe --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.Context.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TicTacToe.Models +{ + using System; + using System.Data.Entity; + using System.Data.Entity.Infrastructure; + + public partial class GameEntities : DbContext + { + public GameEntities() + : base("name=GameEntities") + { + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + + public virtual DbSet Users { get; set; } + } +} diff --git a/TicTacToe/TicTacToe/Models/Game.Context.tt b/TicTacToe/TicTacToe/Models/Game.Context.tt new file mode 100644 index 0000000..509ef32 --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.Context.tt @@ -0,0 +1,636 @@ +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF6.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"Game.edmx"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors); +var itemCollection = loader.CreateEdmItemCollection(inputFile); +var modelNamespace = loader.GetModelNamespace(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +var container = itemCollection.OfType().FirstOrDefault(); +if (container == null) +{ + return string.Empty; +} +#> +//------------------------------------------------------------------------------ +// +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ + +<# + +var codeNamespace = code.VsNamespaceSuggestion(); +if (!String.IsNullOrEmpty(codeNamespace)) +{ +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<# + PushIndent(" "); +} + +#> +using System; +using System.Data.Entity; +using System.Data.Entity.Infrastructure; +<# +if (container.FunctionImports.Any()) +{ +#> +using System.Data.Entity.Core.Objects; +using System.Linq; +<# +} +#> + +<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext +{ + public <#=code.Escape(container)#>() + : base("name=<#=container.Name#>") + { +<# +if (!loader.IsLazyLoadingEnabled(container)) +{ +#> + this.Configuration.LazyLoadingEnabled = false; +<# +} + +foreach (var entitySet in container.BaseEntitySets.OfType()) +{ + // Note: the DbSet members are defined below such that the getter and + // setter always have the same accessibility as the DbSet definition + if (Accessibility.ForReadOnlyProperty(entitySet) != "public") + { +#> + <#=codeStringGenerator.DbSetInitializer(entitySet)#> +<# + } +} +#> + } + + protected override void OnModelCreating(DbModelBuilder modelBuilder) + { + throw new UnintentionalCodeFirstException(); + } + +<# + foreach (var entitySet in container.BaseEntitySets.OfType()) + { +#> + <#=codeStringGenerator.DbSet(entitySet)#> +<# + } + + foreach (var edmFunction in container.FunctionImports) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false); + } +#> +} +<# + +if (!String.IsNullOrEmpty(codeNamespace)) +{ + PopIndent(); +#> +} +<# +} +#> +<#+ + +private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) +{ + if (typeMapper.IsComposable(edmFunction)) + { +#> + + [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")] + <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#> + } +<#+ + } + else + { +#> + + <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#> + { +<#+ + codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter); +#> + <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#> + } +<#+ + if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption)) + { + WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true); + } + } +} + +public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit) +{ +#> + var <#=name#> = <#=isNotNull#> ? + <#=notNullInit#> : + <#=nullInit#>; + +<#+ +} + +public const string TemplateId = "CSharp_DbContext_Context_EF6"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navProp) + { + var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), + navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navProp), + _code.SpaceAfter(Accessibility.ForGetter(navProp)), + _code.SpaceAfter(Accessibility.ForSetter(navProp))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} virtual DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string DbSetInitializer(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} = Set<{1}>();", + _code.Escape(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public static string FixNamespaces(string typeName) + { + return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); + } + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + typeName = FixNamespaces(typeName); + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} +#> \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/Game.Designer.cs b/TicTacToe/TicTacToe/Models/Game.Designer.cs new file mode 100644 index 0000000..16d102a --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.Designer.cs @@ -0,0 +1,10 @@ +// T4 code generation is enabled for model 'C:\Users\rishabh.gupta\documents\visual studio 2015\Projects\TicTacToe\TicTacToe\Models\Game.edmx'. +// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer +// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model +// is open in the designer. + +// If no context and entity classes have been generated, it may be because you created an empty model but +// have not yet chosen which version of Entity Framework to use. To generate a context class and entity +// classes for your model, open the model in the designer, right-click on the designer surface, and +// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation +// Item...'. \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/Game.cs b/TicTacToe/TicTacToe/Models/Game.cs new file mode 100644 index 0000000..7cc0662 --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.cs @@ -0,0 +1,9 @@ +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + diff --git a/TicTacToe/TicTacToe/Models/Game.edmx b/TicTacToe/TicTacToe/Models/Game.edmx new file mode 100644 index 0000000..e51b7ae --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.edmx @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/Game.edmx.diagram b/TicTacToe/TicTacToe/Models/Game.edmx.diagram new file mode 100644 index 0000000..cce1e24 --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.edmx.diagram @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/Game.tt b/TicTacToe/TicTacToe/Models/Game.tt new file mode 100644 index 0000000..4469a98 --- /dev/null +++ b/TicTacToe/TicTacToe/Models/Game.tt @@ -0,0 +1,733 @@ +<#@ template language="C#" debug="false" hostspecific="true"#> +<#@ include file="EF6.Utility.CS.ttinclude"#><#@ + output extension=".cs"#><# + +const string inputFile = @"Game.edmx"; +var textTransform = DynamicTextTransformation.Create(this); +var code = new CodeGenerationTools(this); +var ef = new MetadataTools(this); +var typeMapper = new TypeMapper(code, ef, textTransform.Errors); +var fileManager = EntityFrameworkTemplateFileManager.Create(this); +var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile); +var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef); + +if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile)) +{ + return string.Empty; +} + +WriteHeader(codeStringGenerator, fileManager); + +foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(entity.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false)#> +<#=codeStringGenerator.EntityClassOpening(entity)#> +{ +<# + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity); + var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity); + var complexProperties = typeMapper.GetComplexProperties(entity); + + if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any()) + { +#> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] + public <#=code.Escape(entity)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var navigationProperty in collectionNavigationProperties) + { +#> + this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>(); +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(entity); + if (simpleProperties.Any()) + { + foreach (var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var complexProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(complexProperty)#> +<# + } + } + + var navigationProperties = typeMapper.GetNavigationProperties(entity); + if (navigationProperties.Any()) + { +#> + +<# + foreach (var navigationProperty in navigationProperties) + { + if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many) + { +#> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] +<# + } +#> + <#=codeStringGenerator.NavigationProperty(navigationProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(complex.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#> +{ +<# + var complexProperties = typeMapper.GetComplexProperties(complex); + var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex); + + if (propertiesWithDefaultValues.Any() || complexProperties.Any()) + { +#> + public <#=code.Escape(complex)#>() + { +<# + foreach (var edmProperty in propertiesWithDefaultValues) + { +#> + this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>; +<# + } + + foreach (var complexProperty in complexProperties) + { +#> + this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>(); +<# + } +#> + } + +<# + } + + var simpleProperties = typeMapper.GetSimpleProperties(complex); + if (simpleProperties.Any()) + { + foreach(var edmProperty in simpleProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } + + if (complexProperties.Any()) + { +#> + +<# + foreach(var edmProperty in complexProperties) + { +#> + <#=codeStringGenerator.Property(edmProperty)#> +<# + } + } +#> +} +<# + EndNamespace(code); +} + +foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection)) +{ + fileManager.StartNewFile(enumType.Name + ".cs"); + BeginNamespace(code); +#> +<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#> +<# + if (typeMapper.EnumIsFlags(enumType)) + { +#> +[Flags] +<# + } +#> +<#=codeStringGenerator.EnumOpening(enumType)#> +{ +<# + var foundOne = false; + + foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType)) + { + foundOne = true; +#> + <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>, +<# + } + + if (foundOne) + { + this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1); + } +#> +} +<# + EndNamespace(code); +} + +fileManager.Process(); + +#> +<#+ + +public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager) +{ + fileManager.StartHeader(); +#> +//------------------------------------------------------------------------------ +// +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#> +// +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#> +// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#> +// +//------------------------------------------------------------------------------ +<#=codeStringGenerator.UsingDirectives(inHeader: true)#> +<#+ + fileManager.EndBlock(); +} + +public void BeginNamespace(CodeGenerationTools code) +{ + var codeNamespace = code.VsNamespaceSuggestion(); + if (!String.IsNullOrEmpty(codeNamespace)) + { +#> +namespace <#=code.EscapeNamespace(codeNamespace)#> +{ +<#+ + PushIndent(" "); + } +} + +public void EndNamespace(CodeGenerationTools code) +{ + if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion())) + { + PopIndent(); +#> +} +<#+ + } +} + +public const string TemplateId = "CSharp_DbContext_Types_EF6"; + +public class CodeStringGenerator +{ + private readonly CodeGenerationTools _code; + private readonly TypeMapper _typeMapper; + private readonly MetadataTools _ef; + + public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(typeMapper, "typeMapper"); + ArgumentNotNull(ef, "ef"); + + _code = code; + _typeMapper = typeMapper; + _ef = ef; + } + + public string Property(EdmProperty edmProperty) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + Accessibility.ForProperty(edmProperty), + _typeMapper.GetTypeName(edmProperty.TypeUsage), + _code.Escape(edmProperty), + _code.SpaceAfter(Accessibility.ForGetter(edmProperty)), + _code.SpaceAfter(Accessibility.ForSetter(edmProperty))); + } + + public string NavigationProperty(NavigationProperty navProp) + { + var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType()); + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2} {{ {3}get; {4}set; }}", + AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)), + navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, + _code.Escape(navProp), + _code.SpaceAfter(Accessibility.ForGetter(navProp)), + _code.SpaceAfter(Accessibility.ForSetter(navProp))); + } + + public string AccessibilityAndVirtual(string accessibility) + { + return accessibility + (accessibility != "private" ? " virtual" : ""); + } + + public string EntityClassOpening(EntityType entity) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1}partial class {2}{3}", + Accessibility.ForType(entity), + _code.SpaceAfter(_code.AbstractOption(entity)), + _code.Escape(entity), + _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType))); + } + + public string EnumOpening(SimpleType enumType) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} enum {1} : {2}", + Accessibility.ForType(enumType), + _code.Escape(enumType), + _code.Escape(_typeMapper.UnderlyingClrType(enumType))); + } + + public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter) + { + var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable)) + { + var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null"; + var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")"; + var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))"; + writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit); + } + } + + public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "{0} IQueryable<{1}> {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + _code.Escape(edmFunction), + string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray())); + } + + public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace) + { + var parameters = _typeMapper.GetParameters(edmFunction); + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});", + _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace), + edmFunction.NamespaceName, + edmFunction.Name, + string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()), + _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()))); + } + + public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()); + if (includeMergeOption) + { + paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption"; + } + + return string.Format( + CultureInfo.InvariantCulture, + "{0} {1} {2}({3})", + AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)), + returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + _code.Escape(edmFunction), + paramList); + } + + public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption) + { + var parameters = _typeMapper.GetParameters(edmFunction); + var returnType = _typeMapper.GetReturnType(edmFunction); + + var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())); + if (includeMergeOption) + { + callParams = ", mergeOption" + callParams; + } + + return string.Format( + CultureInfo.InvariantCulture, + "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});", + returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">", + edmFunction.Name, + callParams); + } + + public string DbSet(EntitySet entitySet) + { + return string.Format( + CultureInfo.InvariantCulture, + "{0} virtual DbSet<{1}> {2} {{ get; set; }}", + Accessibility.ForReadOnlyProperty(entitySet), + _typeMapper.GetTypeName(entitySet.ElementType), + _code.Escape(entitySet)); + } + + public string UsingDirectives(bool inHeader, bool includeCollections = true) + { + return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion()) + ? string.Format( + CultureInfo.InvariantCulture, + "{0}using System;{1}" + + "{2}", + inHeader ? Environment.NewLine : "", + includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "", + inHeader ? "" : Environment.NewLine) + : ""; + } +} + +public class TypeMapper +{ + private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName"; + + private readonly System.Collections.IList _errors; + private readonly CodeGenerationTools _code; + private readonly MetadataTools _ef; + + public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors) + { + ArgumentNotNull(code, "code"); + ArgumentNotNull(ef, "ef"); + ArgumentNotNull(errors, "errors"); + + _code = code; + _ef = ef; + _errors = errors; + } + + public static string FixNamespaces(string typeName) + { + return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial."); + } + + public string GetTypeName(TypeUsage typeUsage) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null); + } + + public string GetTypeName(EdmType edmType) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: null); + } + + public string GetTypeName(TypeUsage typeUsage, string modelNamespace) + { + return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace); + } + + public string GetTypeName(EdmType edmType, string modelNamespace) + { + return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace); + } + + public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace) + { + if (edmType == null) + { + return null; + } + + var collectionType = edmType as CollectionType; + if (collectionType != null) + { + return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace)); + } + + var typeName = _code.Escape(edmType.MetadataProperties + .Where(p => p.Name == ExternalTypeNameAttributeName) + .Select(p => (string)p.Value) + .FirstOrDefault()) + ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ? + _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) : + _code.Escape(edmType)); + + if (edmType is StructuralType) + { + return typeName; + } + + if (edmType is SimpleType) + { + var clrType = UnderlyingClrType(edmType); + if (!IsEnumType(edmType)) + { + typeName = _code.Escape(clrType); + } + + typeName = FixNamespaces(typeName); + + return clrType.IsValueType && isNullable == true ? + String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) : + typeName; + } + + throw new ArgumentException("edmType"); + } + + public Type UnderlyingClrType(EdmType edmType) + { + ArgumentNotNull(edmType, "edmType"); + + var primitiveType = edmType as PrimitiveType; + if (primitiveType != null) + { + return primitiveType.ClrEquivalentType; + } + + if (IsEnumType(edmType)) + { + return GetEnumUnderlyingType(edmType).ClrEquivalentType; + } + + return typeof(object); + } + + public object GetEnumMemberValue(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var valueProperty = enumMember.GetType().GetProperty("Value"); + return valueProperty == null ? null : valueProperty.GetValue(enumMember, null); + } + + public string GetEnumMemberName(MetadataItem enumMember) + { + ArgumentNotNull(enumMember, "enumMember"); + + var nameProperty = enumMember.GetType().GetProperty("Name"); + return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null); + } + + public System.Collections.IEnumerable GetEnumMembers(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var membersProperty = enumType.GetType().GetProperty("Members"); + return membersProperty != null + ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null) + : Enumerable.Empty(); + } + + public bool EnumIsFlags(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + var isFlagsProperty = enumType.GetType().GetProperty("IsFlags"); + return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null); + } + + public bool IsEnumType(GlobalItem edmType) + { + ArgumentNotNull(edmType, "edmType"); + + return edmType.GetType().Name == "EnumType"; + } + + public PrimitiveType GetEnumUnderlyingType(EdmType enumType) + { + ArgumentNotNull(enumType, "enumType"); + + return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null); + } + + public string CreateLiteral(object value) + { + if (value == null || value.GetType() != typeof(TimeSpan)) + { + return _code.CreateLiteral(value); + } + + return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks); + } + + public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile) + { + ArgumentNotNull(types, "types"); + ArgumentNotNull(sourceFile, "sourceFile"); + + var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase); + if (types.Any(item => !hash.Add(item))) + { + _errors.Add( + new CompilerError(sourceFile, -1, -1, "6023", + String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict")))); + return false; + } + return true; + } + + public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection) + { + return GetItemsToGenerate(itemCollection) + .Where(e => IsEnumType(e)); + } + + public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType + { + return itemCollection + .OfType() + .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName)) + .OrderBy(i => i.Name); + } + + public IEnumerable GetAllGlobalItems(IEnumerable itemCollection) + { + return itemCollection + .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i)) + .Select(g => GetGlobalItemName(g)); + } + + public string GetGlobalItemName(GlobalItem item) + { + if (item is EdmType) + { + return ((EdmType)item).Name; + } + else + { + return ((EntityContainer)item).Name; + } + } + + public IEnumerable GetSimpleProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetSimpleProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetComplexProperties(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type); + } + + public IEnumerable GetPropertiesWithDefaultValues(EntityType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetPropertiesWithDefaultValues(ComplexType type) + { + return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null); + } + + public IEnumerable GetNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type); + } + + public IEnumerable GetCollectionNavigationProperties(EntityType type) + { + return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many); + } + + public FunctionParameter GetReturnParameter(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters"); + return returnParamsProperty == null + ? edmFunction.ReturnParameter + : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault(); + } + + public bool IsComposable(EdmFunction edmFunction) + { + ArgumentNotNull(edmFunction, "edmFunction"); + + var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute"); + return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null); + } + + public IEnumerable GetParameters(EdmFunction edmFunction) + { + return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef); + } + + public TypeUsage GetReturnType(EdmFunction edmFunction) + { + var returnParam = GetReturnParameter(edmFunction); + return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage); + } + + public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption) + { + var returnType = GetReturnType(edmFunction); + return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType; + } +} + +public static void ArgumentNotNull(T arg, string name) where T : class +{ + if (arg == null) + { + throw new ArgumentNullException(name); + } +} +#> \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Models/User.cs b/TicTacToe/TicTacToe/Models/User.cs new file mode 100644 index 0000000..684205d --- /dev/null +++ b/TicTacToe/TicTacToe/Models/User.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// +// This code was generated from a template. +// +// Manual changes to this file may cause unexpected behavior in your application. +// Manual changes to this file will be overwritten if the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace TicTacToe.Models +{ + using System; + using System.Collections.Generic; + + public partial class User + { + public int Id { get; set; } + public string UserName { get; set; } + public string Password { get; set; } + public Nullable Points { get; set; } + } +} diff --git a/TicTacToe/TicTacToe/Properties/AssemblyInfo.cs b/TicTacToe/TicTacToe/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..852a916 --- /dev/null +++ b/TicTacToe/TicTacToe/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("TicTacToe")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TicTacToe")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8c062e7f-600f-444b-9fe9-396ed8247aec")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TicTacToe/TicTacToe/TicTacToe.csproj b/TicTacToe/TicTacToe/TicTacToe.csproj new file mode 100644 index 0000000..b180ec4 --- /dev/null +++ b/TicTacToe/TicTacToe/TicTacToe.csproj @@ -0,0 +1,240 @@ + + + + + + + Debug + AnyCPU + + + 2.0 + {8C062E7F-600F-444B-9FE9-396ED8247AEC} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + TicTacToe + TicTacToe + v4.5.2 + true + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll + True + + + ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll + True + + + ..\packages\Microsoft.ApplicationInsights.Agent.Intercept.1.2.1\lib\net45\Microsoft.AI.Agent.Intercept.dll + True + + + ..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.0.0\lib\net45\Microsoft.AI.DependencyCollector.dll + True + + + ..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.0.0\lib\net45\Microsoft.AI.PerfCounterCollector.dll + True + + + ..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.0.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll + True + + + ..\packages\Microsoft.ApplicationInsights.Web.2.0.0\lib\net45\Microsoft.AI.Web.dll + True + + + ..\packages\Microsoft.ApplicationInsights.WindowsServer.2.0.0\lib\net45\Microsoft.AI.WindowsServer.dll + True + + + ..\packages\Microsoft.ApplicationInsights.2.0.0\lib\net45\Microsoft.ApplicationInsights.dll + True + + + ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + True + + + + ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll + True + + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + True + + + + + ..\packages\Microsoft.AspNet.Cors.5.2.7\lib\net45\System.Web.Cors.dll + True + + + + + + + + + + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + True + + + ..\packages\Microsoft.AspNet.WebApi.Cors.5.2.7\lib\net45\System.Web.Http.Cors.dll + True + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + True + + + + + + + + + + + + + PreserveNewest + + + EntityModelCodeGenerator + Game.Designer.cs + + + Game.edmx + + + Web.config + + + Web.config + + + + + + TextTemplatingFileGenerator + Game.edmx + Game.Context.cs + + + TextTemplatingFileGenerator + Game.edmx + Game.cs + + + + + Designer + + + + + + + + Global.asax + + + True + True + Game.Context.tt + + + True + True + Game.tt + + + True + True + Game.edmx + + + Game.tt + + + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 53682 + / + http://localhost:53682/ + False + False + + + False + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/TicTacToe.csproj.user b/TicTacToe/TicTacToe/TicTacToe.csproj.user new file mode 100644 index 0000000..e7307f9 --- /dev/null +++ b/TicTacToe/TicTacToe/TicTacToe.csproj.user @@ -0,0 +1,38 @@ + + + + true + 600 + True + False + True + + TicTacToe.Models.GameEntities + False + + + + + + + + CurrentPage + True + False + False + False + + + + + + + + + True + True + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Web.Debug.config b/TicTacToe/TicTacToe/Web.Debug.config new file mode 100644 index 0000000..2e302f9 --- /dev/null +++ b/TicTacToe/TicTacToe/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Web.Release.config b/TicTacToe/TicTacToe/Web.Release.config new file mode 100644 index 0000000..c358444 --- /dev/null +++ b/TicTacToe/TicTacToe/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/Web.config b/TicTacToe/TicTacToe/Web.config new file mode 100644 index 0000000..d66e2b6 --- /dev/null +++ b/TicTacToe/TicTacToe/Web.config @@ -0,0 +1,61 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TicTacToe/TicTacToe/packages.config b/TicTacToe/TicTacToe/packages.config new file mode 100644 index 0000000..ef15ee6 --- /dev/null +++ b/TicTacToe/TicTacToe/packages.config @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/const.js b/const.js new file mode 100644 index 0000000..920043f --- /dev/null +++ b/const.js @@ -0,0 +1 @@ +var localhost = "http://localhost:53682"; \ No newline at end of file diff --git a/databaseschema.PNG b/databaseschema.PNG new file mode 100644 index 0000000000000000000000000000000000000000..1ecc7b70d39d329573bed81eb6ce35208674ed9a GIT binary patch literal 5043 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 bVg0uNnWF5}n36>u00000NkvXXu0mjfg^76m literal 0 HcmV?d00001 diff --git a/img/crackers.gif b/img/crackers.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b43c140e5f014b577609db171c1b99e4840f5d8 GIT binary patch literal 138598 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

=0IHh@ztSf4-G=YMhFK|JaSK5!FZ07D!_k$#Vp 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 - + Tic Tac Toe + + + + + + + + + + +

+
-
+ + + + +
-
+ + + + +
+
-
Player 1
- +
Login To Start
@@ -151,10 +84,12 @@
+
+ \ No newline at end of file diff --git a/index.js b/index.js index 4bd10c4..912e151 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,138 @@ var c = [ 0,0,0,0,0,0,0,0,0]; var gameover = 0; +var is_player_1_loggedin = 0; +var is_player_2_loggedin = 0; +var player1 = {}; +var player2 = {}; +var chance; + +//Function to check whether both players are logged in +function areBothLoggedIn() +{ + console.log(is_player_1_loggedin); + console.log(is_player_2_loggedin); + return is_player_1_loggedin && is_player_2_loggedin; +} + +//Function to get Player name +// Not Used function getPlayerName(x){ return x == 1 ? 'Player 1' : 'Player 2'; } +//changes game message + function changeMessage(message){ $('.message').text(message); } + +//Changes UI and saves player data after login +function afterLogin(player,id,data) +{ + + player.find('.login-txt').addClass('display-none'); + player.find('.player-details').removeClass('display-none'); + player.find('.player-name').text(data.username); + player.find('.player-points').text(data.points + ' Pts'); + player.find('.logout').removeClass('display-none'); + window['is_player_' + id + '_loggedin'] = 1; + localStorage.setItem("username" + id,data.username); + window['player'+id].username = data.username; + window['player'+id].points = data.points; + if(areBothLoggedIn()) + { + startGame(); + } + +} + +//Check if previously logged in players are there +function checkPrevPlayers() +{ + if(localStorage.getItem('username1') != null) + { + let username1 = localStorage.getItem('username1'); + $.ajax({ + url:localhost + '/api/Users/'+username1+'/Points', + statusCode : { + '200' : function(data) + { + let player = $('.player').eq(0); + afterLogin(player,1,data); + + } + } + }) + + } + + if(localStorage.getItem('username2') != null) + { + let username2 = localStorage.getItem('username2'); + $.ajax({ + url:localhost + '/api/Users/'+username2+'/Points', + statusCode : { + '200' : function(data) + { + let player = $('.player').eq(1); + afterLogin(player,2,data) + } + } + }) + + } + +} + +//Changes UI and update points on frontend & database if one wins +function updateWinner(id) +{ + changeMessage('Player '+id + ' Wins'); + player1.points = player1.points + (id==1?10:-5); + player2.points = player2.points + (id==2?10:-5); + $('.player-points').eq(0).text(player1.points + ' Pts'); + $('.player-points').eq(1).text(player2.points + ' Pts'); + console.log('winner is : '+ id); + $('.crackers-img').removeClass('display-none'); + savePoints(player1); + savePoints(player2); +} + +//Save points to database +function savePoints(player) +{ + $.ajax({ + url:localhost + '/api/Users', + 'type':'PATCH', + data: { 'UserName' : player.username, + 'Points' : player.points + }, + + statusCode : { + '200' : function(){ + console.log('saved'); + } + } + }) +} + + +//Chooses who starts first? + function getRandomChance(){ return Math.floor(Math.random()*2) == 0?-1:1; } -var chance = getRandomChance(); -changeUI(); +//Function to initiate the game +function startGame() +{ + chance = getRandomChance(); + changeUI(); +} + +//Changes ui on change of turn of players function changeUI(){ $('.player').removeClass('player-highlighted'); @@ -22,6 +140,8 @@ function changeUI(){ changeMessage(getPlayerName(chance) + " Chance"); } + +//Function to alternate between players function changeChance(){ if(chance == 1) chance = -1; @@ -31,6 +151,8 @@ function changeChance(){ changeUI(); } + +//Function to check win/lose/draw cases function check() { @@ -43,11 +165,11 @@ function check() sum +=c[j]; if(sum == 3) - { changeMessage('Player 1 Wins'); + { updateWinner(1); return 1; } else if(sum == -3) - { changeMessage('Player 2 Wins'); + { updateWinner(2); return 1; } console.log(c); @@ -61,11 +183,11 @@ function check() console.log("sum : " + sum); if(sum == 3) - {changeMessage('Player 1 Wins'); + {updateWinner(1); return 1; } else if(sum == -3) - { changeMessage('Player 2 Wins'); + { updateWinner(2); return 1; } console.log(c); @@ -75,11 +197,11 @@ function check() if((c[0] == c[4]) && (c[4] == c[8]) && (c[0]!=0)) { if(c[0] == 1) - { changeMessage('Player 1 Wins'); + { updateWinner(1); return 1; } else - { changeMessage('Player 2 wins'); + { updateWinner(2); return 1; } } @@ -87,11 +209,11 @@ function check() if((c[2] == c[4]) && (c[4] == c[6]) && (c[2]!=0)) { if(c[2] == 1) - { changeMessage('Player 1 Wins'); + { updateWinner(1); return 1; } else - { changeMessage('Player 2 wins'); + { updateWinner(2); return 1; } } @@ -114,7 +236,16 @@ function check() } +//Handles click on each cell of tic tac toe + $('td').click(function(){ + + if(!areBothLoggedIn()) + { + alert('Both Players Login to Continue'); + return; + } + if(!gameover) { var t = chance == 1?'X':'0'; var pos = Number($(this).attr('id')); @@ -145,6 +276,56 @@ $('td').click(function(){ }) +//Restart -> reload the page + $('.restart-btn').click(function(){ window.location.reload(); }) + +// Login Form Submit Function +$(document).on('submit','.login-form',function(e){ + e.preventDefault(); + alert('in login'); + console.log($(this).serialize()); + var form = $(this); + $.ajax({ + url:localhost + '/api/login', + 'type':'POST', + data:$(this).serialize(), + statusCode : { + '400':function(){ + console.log('Bad Request'); + }, + '404' : function(){ + alert('Login Failed'); + }, + '200' : function(data){ + var id = form.find('input[type=hidden]').val(); + console.log(id); + form.parent().hide(); + let player = form.closest('.player'); + afterLogin(player,id,data); + + } + } + }) +}) + + +//Logout Function +$('.logout').click(function(){ + var id = $(this).next().find('input[type=hidden]').val(); + localStorage.removeItem("username"+id); + window.location.reload(); +}); + +//On click toggle login dropdown +$('.login-txt').click(function(){ + $(this).parent().find('.login-dropdown').toggle(); +}) + +checkPrevPlayers(); + + + + diff --git a/style.css b/style.css new file mode 100644 index 0000000..80dcb50 --- /dev/null +++ b/style.css @@ -0,0 +1,153 @@ + +body{ + background-color: lightblue; +} +table{ + border-collapse: collapse; +} +.cell{ + width: 120px; + height:120px; + background-color: antiquewhite; + text-align: center; + font-size: 70px; + transition: all 0.4s linear 0.4s; +} + +.border-right{ + border-right: 1px solid red; +} +.border-bottom{ + border-bottom: 1px solid red; +} +.border-left{ + border-left: 1px solid red; +} + +.game-wrap{ + display: flex; + flex-direction: column; + align-items: center; +} +.table-wrap{ + position: relative; + display: flex; + justify-content: center; +} +.players-wrap{ + display: flex; + justify-content: space-between; + padding: 10px 100px; + +} +.player-icon{ + width: 70px; + height: 70px; + background-color: azure; + border-radius: 50%; + margin-right: 20px; + +} +.player{ + display: flex; + align-items: center; + padding:10px 50px; + position: relative; +} +.message{ + font-size: 32px; + margin-bottom: 20px; + padding: 14px; +} +.message-win{ + animation: textanim 2s infinite; +} +.crackers-img{ + position: absolute; + z-index: -1; + top: -200px; + +} +.player-details{ + font-size: 20px; +} +.player-highlighted{ + background-color: #0000001f; + border-radius: 5px; +} +.restart-btn{ + margin-top: 30px; + padding: 12px 40px; + background-color: #072235; + border: none; + border-radius: 20px; + font-size: 16px; + color: white; + display: none; + cursor: pointer; +} +.login-dropdown{ + background-color: #ffffff6e; + padding: 20px; + position: absolute; + top: 90px; + right: 0px; + display: none; + z-index: 1; + +} +.login-txt{ + cursor: pointer; +} + + +.login-form{ + display: flex; + flex-direction: column; +} +.display-none{ + display: none; +} + +.login-btn{ + margin-top: 10px; + padding: 5px 20px; + background-color: #072235; + border: none; + border-radius: 20px; + font-size: 12px; + color: white; + cursor: pointer; + align-self: center; +} + +.win-box{ + width: 90px; + height: 90px; + font-size: 50px; +} + +.logout{ + margin-left: 10px; + cursor: pointer; +} +@keyframes textanim { + 0% {transform: scale(1,1);} + 50% {transform: scale(1.3,1.3);} + 100% {transform: scale(1,1);} +} +@media only screen and (min-width: 600px) and (max-width:960px) { + .players-wrap{ + padding: 10px 30px !important; + } +} +@media only screen and (min-width: 320px) and (max-width:599px) { + .players-wrap{ + flex-wrap: wrap !important; + justify-content: center; + padding: 10px 10px !important; + } + .login-dropdown{ + background-color: white; + } +}