Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master", "CSDT-2024-1" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
17 changes: 17 additions & 0 deletions .github/workflows/sonarqube.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: SonarQube analysis
on:
push:
branches: [ "main" ]
workflow_dispatch:
jobs:
Analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Analyze with SonarQube
uses: SonarSource/sonarqube-scan-action@v2.0.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on SonarQube, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }} # Add the URL of your instance to the variables of this repo with the name SONAR_HOST_URL (Settings > Secrets > Actions > add new repository secret)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1,037 changes: 1,037 additions & 0 deletions .vs/PokerOdds/config/applicationhost.config

Large diffs are not rendered by default.

129 changes: 129 additions & 0 deletions .vs/PokerOdds/v17/DocumentLayout.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"Version": 1,
"WorkspaceRootPath": "C:\\dev\\PokerOdds-JuanContreras\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.mvc.web.tests\\controllers\\texasholdemcontrollertest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|solutionrelative:pokerodds.mvc.web.tests\\controllers\\texasholdemcontrollertest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.mvc.web.tests\\controllers\\valuescontrollertest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|solutionrelative:pokerodds.mvc.web.tests\\controllers\\valuescontrollertest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{DC338043-19DC-48FF-AC51-FF11E3CE9C64}|PokerOdds.Mvc.Web\\PokerOdds.Mvc.Web.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.mvc.web\\controllers\\texasholdemcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{DC338043-19DC-48FF-AC51-FF11E3CE9C64}|PokerOdds.Mvc.Web\\PokerOdds.Mvc.Web.csproj|solutionrelative:pokerodds.mvc.web\\controllers\\texasholdemcontroller.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.mvc.web.tests\\handevaluator\\handevaluatortest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{BF77FCB2-947E-441F-8D44-C47E15D300BF}|PokerOdds.Mvc.Web.Tests\\PokerOdds.Mvc.Web.Tests.csproj|solutionrelative:pokerodds.mvc.web.tests\\handevaluator\\handevaluatortest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{5E185038-7473-42A9-B303-B2AA147C1157}|PokerOdds.HandEvaluator\\PokerOdds.HandEvaluator.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.handevaluator\\handevaluator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{5E185038-7473-42A9-B303-B2AA147C1157}|PokerOdds.HandEvaluator\\PokerOdds.HandEvaluator.csproj|solutionrelative:pokerodds.handevaluator\\handevaluator.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{0DE4795E-6BCF-4C60-9C87-83F72862E6DA}|PokerOdds.Web.OWIN\\PokerOdds.Web.OWIN.csproj|C:\\dev\\PokerOdds-JuanContreras\\pokerodds.web.owin\\startup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{0DE4795E-6BCF-4C60-9C87-83F72862E6DA}|PokerOdds.Web.OWIN\\PokerOdds.Web.OWIN.csproj|solutionrelative:pokerodds.web.owin\\startup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 3,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{3ae79031-e1bc-11d0-8f78-00a0c9110057}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{2c59525e-9c14-4bfd-bc18-3a5ae7eb7dbd}"
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{31879382-50e1-3e5b-88b6-69f415918fa5}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "TexasHoldemControllerTest.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\Controllers\\TexasHoldemControllerTest.cs",
"RelativeDocumentMoniker": "PokerOdds.Mvc.Web.Tests\\Controllers\\TexasHoldemControllerTest.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\Controllers\\TexasHoldemControllerTest.cs",
"RelativeToolTip": "PokerOdds.Mvc.Web.Tests\\Controllers\\TexasHoldemControllerTest.cs",
"ViewState": "AQIAABsAAAAAAAAAAAAAAC8AAAA+AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-20T03:52:10.186Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "HandEvaluatorTest.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\HandEvaluator\\HandEvaluatorTest.cs",
"RelativeDocumentMoniker": "PokerOdds.Mvc.Web.Tests\\HandEvaluator\\HandEvaluatorTest.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\HandEvaluator\\HandEvaluatorTest.cs",
"RelativeToolTip": "PokerOdds.Mvc.Web.Tests\\HandEvaluator\\HandEvaluatorTest.cs",
"ViewState": "AQIAAAkAAAAAAAAAAAAAAB8AAAA1AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-20T03:40:57.143Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "HandEvaluator.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.HandEvaluator\\HandEvaluator.cs",
"RelativeDocumentMoniker": "PokerOdds.HandEvaluator\\HandEvaluator.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.HandEvaluator\\HandEvaluator.cs",
"RelativeToolTip": "PokerOdds.HandEvaluator\\HandEvaluator.cs",
"ViewState": "AQIAADAAAAAAAAAAAAAAAOQAAAAbAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-20T03:39:16.759Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "Startup.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Web.OWIN\\Startup.cs",
"RelativeDocumentMoniker": "PokerOdds.Web.OWIN\\Startup.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Web.OWIN\\Startup.cs",
"RelativeToolTip": "PokerOdds.Web.OWIN\\Startup.cs",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAMAAAAdAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-20T03:23:31.529Z"
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "ValuesControllerTest.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\Controllers\\ValuesControllerTest.cs",
"RelativeDocumentMoniker": "PokerOdds.Mvc.Web.Tests\\Controllers\\ValuesControllerTest.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web.Tests\\Controllers\\ValuesControllerTest.cs",
"RelativeToolTip": "PokerOdds.Mvc.Web.Tests\\Controllers\\ValuesControllerTest.cs",
"ViewState": "AQIAAA8AAAAAAAAAAAAiwBAAAAAHAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-20T03:21:56.93Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "TexasHoldemController.cs",
"DocumentMoniker": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web\\Controllers\\TexasHoldemController.cs",
"RelativeDocumentMoniker": "PokerOdds.Mvc.Web\\Controllers\\TexasHoldemController.cs",
"ToolTip": "C:\\dev\\PokerOdds-JuanContreras\\PokerOdds.Mvc.Web\\Controllers\\TexasHoldemController.cs",
"RelativeToolTip": "PokerOdds.Mvc.Web\\Controllers\\TexasHoldemController.cs",
"ViewState": "AQIAAC4AAAAAAAAAAAAqwEYAAAAbAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2024-03-09T03:45:43.897Z"
}
]
}
]
}
]
}
Binary file added .vs/PokerOdds/v17/TestStore/0/001.testlog
Binary file not shown.
Binary file added .vs/PokerOdds/v17/TestStore/0/testlog.manifest
Binary file not shown.
125 changes: 125 additions & 0 deletions CSDT-2024.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Code Smells #
- PokerOdds.Mvc.Web.Controllers.TexasHoldemController

### Problema 1 (Magic Numbers)
Se está utilizando el número 10 directamente en el código. Sería mejor declarar esta constante como una variable o propiedad con un nombre descriptivo
~~~csharp

if (stopWatch.Elapsed > TimeSpan.FromSeconds(10))
...
//Tecnica de refactor para el codigo : Replace Magic Literal/Numbers
int stopWatchSeconds = 10;
int cardsNumber = 7;
int twoCards = 2;
int fiveCards = 5;
long winner = 1.0;
long HalfCreditsTies = 0.5;
long Percentage = 100.0;
//Ya corregido en Codigo
~~~
### Problema 2 (Manejo de Excepciones)
No hay manejo explícito de excepciones en el código. Sería útil agregar bloques try-catch para manejar posibles excepciones y proporcionar información detallada en caso de errores.
~~~csharp


//Tecnica de refactor para el codigo : se Agregan bloques try catch para tener control de excepciones
[OutputCache]
public TexasHoldemOdds Get(string pocket, string board)
{
try
{
...
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return null;
}
}
//Ya corregido en Codigo
~~~

### Problema 3 (Long Method)
El método Get es bastante largo y realiza múltiples funciones. Sería beneficioso dividirlo en métodos más pequeños y específicos para mejorar la legibilidad y mantener la coherencia con el principio de responsabilidad única
~~~csharp

//Refactor :
//he encapsulado la lógica en tres métodos (IterateOpponentHands, IterateBoards, y EvaluateHands) dividiendo el codigo en metodos mas pequeños
public TexasHoldemOdds Get(string pocket, string board)
{
...
}

private void IterateOpponentHands(ulong partialBoard, ulong playerMask, double[] playerWins, double[] opponentWins, ref long count, ref Stopwatch stopWatch)
{
...
}

private void IterateBoards(ulong partialBoard, ulong playerMask, double[] playerWins, double[] opponentWins, ref long count, ref Stopwatch stopWatch, ulong opponentMask)
{
...
}

private void EvaluateHands(ulong playerMask, ulong opponentMask, double[] playerWins, double[] opponentWins, ref long count, ref Stopwatch stopWatch, ulong boardMask)
{
...
}

private void CreateOutcomes(double[] playerWins, long count, List<PokerOutcome> outcomes)
{
...
}
//ya corregido en codigo
~~~
# Clean Code + XP Practices #
Analizar las características de Clean Code vistas en clase e indicar cuales de estas se están cumpliendo y argumentar, de las que no se están cumpliendo indicar algunas recomendaciones
## Clean Code ##
### Código enfocado
-PokerOdds.Mvc.Web.Controllers.TexasHoldemController
Como se menciona en el apartado de Code Smells, el método Get es bastante largo y realiza múltiples funciones. Se dividió en métodos más pequeños y específicos para mejorar la legibilidad y mantener la coherencia con el principio de responsabilidad única
### Regla del Boy Scout
Revisando los commits del autor del repo, se evidencia un constante refactor sumado a la solución de los code Smells identificados por mi parte en la actividad anterior, por lo tanto, cumple estas características.
![Descripción de la imagen](/images/BoyScout.png)
### Entendible
Nuestro código cumple con el principio YAGNI pero no con el principio KIS(S), esto se debe a que no toda la lógica se encuentra fácil de comprender y mantiene métodos grandes que se podría dividir en métodos más pequeños y claros
### Escalable
### Duplicidad
En el Código no existen métodos que repitan funciones de otras, entonces cumple con esta característica
### Abstracción
-PokerOdds.Mvc.Web.Controllers.TexasHoldemController
-PokerOdds.HandEvaluator.HandAnalysis.cs
Son solo un par de ejemplos donde no se cumple la Abstracción esto se debe a que las clases además de ser extensas poseen métodos que para solucionar esto, podrían dividirse en métodos más sencillos para facilitar la lectura del código.
### Testeable
-PokerOdds.Mvc.Web.Tests/Controllers/ValuesControllerTest.cs
A pesar de contar con pruebas estas carecen de extensión, por lo que no se prueban todas las funcionalidades de la solución, como recomendación se deberían extender las pruebas ya que en un entorno real probablemente por el coverage un paso a producción de este código no sería posible.
### Principio menor asombro
No lo cumple, por ejemplo si revisamos el archivo PokerOdds.HandEvaluator.HandAnalysis.cs dada la extensión del método si realiza lo que su nombre indica pero no se limita solo a esto , la recomendación seria nuevamente dividir los métodos en varios más pequeños y descriptivos.
## Principios SOLID ##
### Principios que se cumplen:
SRP (Principio de responsabilidad única): Las clases en general tienen una única responsabilidad bien definida.
OCP (Principio abierto-cerrado): Las clases están abiertas para la extensión pero cerradas para la modificación.
LSP (Principio de sustitución de Liskov): Las clases derivadas pueden sustituir a sus clases base sin cambiar el comportamiento del programa.
DIP (Principio de inversión de dependencias): Las clases dependen de abstracciones, no de implementaciones concretas.
###Principios que no se cumplen:
ISP (Principio de interfaz de segregación): Algunas interfaces podrían dividirse en interfaces más pequeñas y específicas.
### Ejemplos de cómo se cumplen los principios SOLID:
La clase HandEvaluator tiene la responsabilidad de evaluar la mano de un jugador.
La clase PocketHands es abstracta y no se puede instanciar directamente.
La clase Straight hereda de la clase Hand y puede sustituirla en cualquier contexto.
La clase IHandEvaluator define una interfaz que puede ser implementada por diferentes clases.
### Ejemplos de cómo no se cumplen los principios SOLID:
La interfaz IHandEvaluator contiene métodos que no son necesarios para todas las clases que la implementan.
La clase HandEvaluator crea instancias de clases concretas, como Straight y Flush.
### Recomendaciones:
Dividir la interfaz IHandEvaluator en interfaces más pequeñas y específicas.
Usar la inyección de dependencias para crear instancias de clases concretas
## XP Practices ##
### Pruebas del cliente
Los clientes participan en las pruebas del software para asegurar que cumple con sus necesidades, si el robot que ayuda a calcular probabilidades no sirve en un entorno real, toca entrar a revisar como ajustarlo para que sea útil.
### Diseño simple
Se busca crear un diseño simple y fácil de entender, lo que facilita el mantenimiento del software, así como está actualmente puede ser complejo comprender partes del código y dificultar su mantenimiento.
### Refactorización
Se mejora el código de forma continua para hacerlo más legible, mantenible y extensible, se puede realizar para aplicar el diseño simple.
### Retroalimentación
Se fomenta la retroalimentación entre los miembros del equipo y con los usuarios.

Loading